Reputation: 159
I have Parent component which include child component aswell. I pass some props to child component from parent. My problem is when i change slider to get new value on parent component, re render does not work on Parent. this causes not re render child component as well.
when changing slider, the function get executed and state is changed with new value. But this setstate is not trigger rerender. I am debugging the below code, console logs are like this(changing slider to 1 from 0);
delay -> 0
delay timetypes -> 0 (6 times executed)
delay -> 1
and when i touch one of the touchable opacities,gets this.state.delay = 0 but i changed 0 to 1 via slider.
// welcome.js
export default class welcome extends Component {
constructor(props) {
super(props);
this.state = {
GridViewItems: [
{ key: "1 min game", min: 1, sec: 0 },
{ key: "3 min game", min: 3, sec: 0 },
{ key: "5 min game", min: 5, sec: 0 },
{ key: "7 min game", min: 7, sec: 0 },
{ key: "10 min game", min: 10, sec: 0 },
{ key: "15 min game", min: 15, sec: 0 }
],
value : 0
};
}
GetGridViewItem(item) {
Alert.alert(item);
}
change(value) {
console.log("change value -> " + value );
this.setState({
value: value
})}
render() {
console.log("delay -> " + this.state.value);
return (
<View style={styles.MainContainer}>
<Text style={styles.welcomeText}>Welcome ChessClock</Text>
<Text style={styles.text}>Delay Time: {this.state.value}</Text>
<Slider
style = {styles.slider}
step={1}
maximumValue={20}
value={this.state.value}
onValueChange={(val)=> this.setState({value: val})}
/>
<FlatList
data={this.state.GridViewItems}
renderItem={({ item }) => (
<TimerTypes
navigation={this.props.navigation}
BlockStyle={styles.GridViewBlockStyle}
TextStyle={styles.GridViewInsideTextItemStyle}
title={item.key}
time={item.min * 60 + item.sec}
delay = {this.state.value}
/>
)}
numColumns={2}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
justifyContent: "center",
flex: 1,
margin: 10,
paddingTop: Platform.OS === "ios" ? 20 : 0
},
GridViewBlockStyle: {
justifyContent: "center",
flex: 1,
alignItems: "center",
height: 100,
margin: 5,
backgroundColor: "#05BC87"
},
GridViewInsideTextItemStyle: {
color: "#fff",
padding: 10,
fontSize: 18,
justifyContent: "center"
},
welcomeText: {
color: "#0F2284",
padding: 60,
fontSize: 30,
justifyContent: "center",
textAlign: "center"
},
text: {
fontSize: 20,
justifyContent: "center",
marginLeft:10
},
slider: {
width: '100%',
marginBottom: 25,
justifyContent: "center",
alignItems : "center"
}
});
// timeTypes
export default class timeTypes extends Component {
constructor(props) {
super(props);
this.state = {
delay : props.delay
}
}
componentWillReceiveProps(nextProps) {
this.setState({ delay: nextProps.delay });
}
render() {
console.log("delay timetypes -> " + this.props.delay);
console.log("delay timetypes -> " + this.state.delay);
return (
<TouchableOpacity onPress={() => this.props.navigation.navigate('Home', {
time: this.props.time,
delay : this.state.delay
})}
style={this.props.BlockStyle} >
<Text style={this.props.TextStyle}>
{this.props.title}
</Text>
</TouchableOpacity >
);
}
}
The happy path should be when changing slider to get new number, parent will rerender and child should get the new value.
github repo: https://github.com/Erkanerkisi/ChessClock
Upvotes: 1
Views: 2886
Reputation: 6742
According to the docs:
FlatList is a PureComponent which means that it will not re-render if props remain shallow-equal. Make sure that everything your renderItem function depends on is passed as a prop (e.g. extraData) that is not === after updates, otherwise your UI may not update on changes. This includes the data prop and parent component state.
So try adding extraData={ this.state.value }
to your FlatList component
Upvotes: 3