javascript - 更改父状态时如何重新渲染子组件?
问题描述
我有父组件,其中也包括子组件。我将一些道具从父组件传递给子组件。我的问题是当我更改滑块以在父组件上获取新值时,重新渲染在父组件上不起作用。这也导致不重新渲染子组件。
更改滑块时,将执行函数并使用新值更改状态。但是这个 setstate 不会触发重新渲染。我正在调试下面的代码,控制台日志是这样的(将滑块从0更改为1);
delay -> 0
delay timetypes -> 0 (6 times executed)
delay -> 1
当我触摸其中一个可触摸的不透明度时,得到 this.state.delay = 0 但我通过滑块将 0 更改为 1。
// 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 >
);
}
}
快乐的路径应该是在更改滑块以获取新数字时,父级将重新渲染,子级应该获得新值。
解决方案
根据文档:
FlatList 是一个 PureComponent,这意味着如果 props 保持浅层相等,它将不会重新渲染。确保您的 renderItem 函数所依赖的所有内容都作为更新后不 === 的 prop(例如 extraData)传递,否则您的 UI 可能不会在更改时更新。这包括数据道具和父组件状态。
所以尝试添加extraData={ this.state.value }
到你的 FlatList 组件
推荐阅读
- javascript - 想要每获得 100 分就增加 1 级,级别计数器不起作用
- c# - 尝试在 ASP.net Web API 中发生授权之前使用 OWIN 注入授权标头
- r - 为什么 sparklyr 函数 spark_read_csv 需要这么长时间并最终刹车?
- javascript - 数据变量返回为 __ob__
- java - 如何强制 Java 编译器只编译我指定的源文件?
- python - 如何将 request.user 正确发送到模型表单?
- c# - 为什么 dapper 在进行选择时为 Guid 返回全零,但表中的 guid 值设置正确?
- haskell - 字符串的二进制表示
- python - Pandas 根据条件提取行,但保留旧行索引
- android - AOSP 汽车方向改变