При свайпе списка пар в компоненте lesson list меняется стейт индекс. Также в компоненте dataslider при нажатии на число дня тоже меняется стейт с индексом.Нужно синхронизировать стейты, чтобы при изменении стейта в data slider изменялся стейт и в lesson list и наоборот.Желательно без использования redux.
Lesson list
import React, { useState, useEffect, useRef, useMemo, useContext } from 'react';
import { StyleSheet, Text, View, FlatList, Dimensions, ScrollView } from 'react-native'
import AntDesign from '@expo/vector-icons/AntDesign';
const { width } = Dimensions.get('screen');
const LessonList = ({ data, index, setIndex }) => {
//const index = useContext(IndexContext);
const lessonsRef = React.useRef<FlatList>()
return (
<FlatList
ref={lessonsRef}
initialNumToRender={3}
initialScrollIndex={index}
data={data.days}
maxToRenderPerBatch={3}
keyExtractor={(item) => item.date}
getItemLayout={(data, index) => (
{length: width, offset: width * index, index}
)}
onMomentumScrollEnd={ev => {
setIndex(Math.floor(ev.nativeEvent.contentOffset.x / width))
}}
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
renderItem={({ item, index: fIndex }) => {
return (
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.lessons_scrollview}>
{item.lessons.map((item) => (
<Lesson key={item.id} item={item} />
))}
</ScrollView>
);
}}
/>
);
}
const Lesson = ({ item }) => {
return (
<View style={styles.lessons}>
<View style={styles.lesson_time}>
<Text style={styles.lesson_time_list_text}>{item.starttime}</Text>
<Text style={styles.lesson_time_end_list_text}>{item.endtime}</Text>
</View>
<View style={styles.lesson_card}>
<Text style={styles.lesson_card_name}>{item.name}</Text>
<Text style={styles.lesson_card_description}>{item.description}</Text>
<Text style={styles.lesson_card_locate}>
<AntDesign name="enviromento" size={16} color="white" />
{item.location}
</Text>
<Text style={styles.lesson_card_teacher}>
<AntDesign name="user" size={16} color="white" />
{item.teacher}
</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
lessons_scrollview: {
paddingHorizontal: 15,
width: width,
paddingTop: 15,
},
lessons: {
flexDirection: "row",
},
lesson_time_text: {
fontFamily: "eUkraineBold",
fontSize: 9,
paddingRight: 30,
color: "#BCC1CD",
},
lesson_time: {
flexDirection: "column",
paddingRight: 9,
borderRightWidth: 1,
borderRightColor: "#FAF9F9",
},
lessons_text: {
fontFamily: "eUkraineBold",
fontSize: 9,
color: "#BCC1CD",
},
lesson_time_list: {
flexDirection: "column",
paddingTop: 14,
},
lesson_time_list_text: {
fontFamily: "eUkraineMedium",
fontSize: 14,
},
lesson_time_end_list_text: {
fontFamily: "eUkraineMedium",
fontSize: 14,
color: "#BCC1CD",
},
lesson_card: {
flexDirection: "column",
marginLeft: 16,
backgroundColor: "#4DC591",
borderRadius: 16,
paddingTop: 16,
paddingLeft: 16,
paddingBottom: 17,
flex: 1,
marginBottom: 16,
},
lesson_card_name: {
fontFamily: "eUkraineBold",
fontSize: 13,
color: "#ffff",
},
lesson_card_description: {
fontFamily: "eUkraineMedium",
fontSize: 10,
paddingTop: 4,
color: "#ffff",
},
lesson_card_locate_img: {
height: 16,
width: 16,
marginRight: 50,
tintColor: "#FFFFFF",
},
lesson_card_locate: {
fontFamily: "eUkraineRegular",
fontSize: 10,
paddingTop: 15,
color: "#ffff",
},
lesson_card_teacher_img: {
//marginRight: 500,
},
lesson_card_teacher: {
fontFamily: "eUkraineRegular",
fontSize: 10,
paddingTop: 3,
color: "#ffff",
},
});
export default LessonList
Data slider
import React, { useState, useEffect, useRef, useMemo } from 'react';
import { TouchableOpacity, FlatList, StyleSheet, Text, View, Dimensions } from 'react-native';
import Moment from 'react-moment';
import moment from 'moment';
import 'moment/locale/uk';
const { width } = Dimensions.get('screen');
const DateSlider = ({ data, index, setIndex }) => {
const _spacing = 11;
const _colors = {
active: `#FF7648`,
inactive: `#fff`,
};
const [startday, setstartday] = useState(updatestartday());
const ref = useRef<FlatList>(null);
useEffect(() => {
const interval = setInterval(() => setstartday(updatestartday()), 60000);
return () => clearInterval(interval);
}, []);
function updatestartday() {
console.log('Update Start Week Day');
return moment().subtract(1, 'week').startOf('week');
}
const generatedayslist = useMemo(() => {
let date = []
let day = startday.clone()
let i = 0;
while (i++ < 21){
date.push(day.clone())
day.add(1, 'day')
}
return date
}, [startday])
//const [index, setIndex] = useState(setindexday());
function setindexday() {
let i = 0;
while (i++ < 21){
if (moment(generatedayslist[i]).date() == moment().date())
break;
}
return i
}
useEffect(() => {
ref.current?.scrollToIndex({
index: index,
animated: true,
viewPosition: 0,
viewOffset: _spacing
})
}, [index])
return (
<FlatList
ref={ref}
initialNumToRender={8}
initialScrollIndex={index}
getItemLayout={(data, index) => (
{length: 54.5, offset: 54.5 * index, index}
)}
data={generatedayslist}
keyExtractor={(item) => item}
contentContainerStyle={{ paddingLeft: _spacing, paddingBottom: 25 }}
showsHorizontalScrollIndicator={false}
horizontal
renderItem={({ item, index: fIndex }) => {
return (
<TouchableOpacity onPress={() => { setIndex(fIndex) }}>
<View
style={{
marginRight: _spacing,
borderRadius: 10,
backgroundColor:
fIndex == index ? _colors.active : _colors.inactive,
width: 43
}}>
<Moment element={Text} style={fIndex == index ? styles.day_flatlist_select
: styles.day_flatlist} format='dd'>{item}</Moment>
<Moment element={Text} style={fIndex == index ? styles.day_flatlist_select
: styles.day_flatlist} format='D'>{item}</Moment>
</View>
</TouchableOpacity>
);
}}
/>
);
}
const styles = StyleSheet.create({
day_flatlist: {
fontFamily: 'eUkraineBold',
fontSize: 13,
textTransform: 'uppercase',
textAlign: 'center',
color: '#000',
},
day_flatlist_select: {
fontFamily: 'eUkraineBold',
fontSize: 13,
textTransform: 'uppercase',
textAlign: 'center',
color: '#FFF',
},
});
export default DateSlider