Answer the question
In order to leave comments, you need to log in
How to synchronize the state in two different components?
When you swipe the list of pairs in the lesson list component, the state index changes. Also, in the dataslider component, when you click on the number of the day, the state with the index also changes. You need to synchronize the states so that when the state changes in the data slider, the state changes in the lesson list and vice versa. Preferably without using 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
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
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question