【问题标题】:How to re-render child component when Parent state is changed?更改父状态时如何重新渲染子组件?
【发布时间】:2019-04-28 10:16:04
【问题描述】:

我有父组件,其中也包括子组件。我将一些道具从父组件传递给子组件。我的问题是当我更改滑块以在父组件上获取新值时,重新渲染在父组件上不起作用。这也导致不重新渲染子组件。

当改变滑块时,函数被执行并且状态被改变为新值。但是这个 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 >
        );
    }
}

快乐的路径应该是更改滑块以获取新数字时,父级将重新渲染,子级应获取新值。

github 仓库:https://github.com/Erkanerkisi/ChessClock

【问题讨论】:

  • 您是否尝试将extraData={ this.state.value } 添加到您的 FlatList 组件?

标签: javascript react-native


【解决方案1】:

根据文档:

FlatList 是一个 PureComponent,这意味着它不会重新渲染 道具保持浅层相等。确保所有你的 renderItem 函数取决于作为道具(例如extraData)传递,而不是 === 更新后,否则您的 UI 可能不会在更改时更新。这包括 data prop 和父组件状态。

所以尝试将extraData={ this.state.value } 添加到您的 FlatList 组件

【讨论】:

  • 谢谢。有效。现在我遇到了问题。实际上组件没有问题,但是相同的道具不会导致渲染子。
  • 我没有得到问题...当您将相同的道具传递给您的 TimeTypes 组件时...预期的行为不是重新渲染组件
  • 如您所见,我一直在为时间类型赋予不同的价值。但是时间类型在平面列表中,我没有对平面列表进行任何更改。结果 flatlist 没有看到任何变化,也没有呈现它自己和孩子。
  • 即使在将extraData={ this.state.value } 传递给您的 FlatList 之后,您的 TimeTypes 组件也不会重新渲染? ...在您将 extraData 字段添加到 FlatList 之后...当您的 value 状态更改时,您的 TimeTypes 组件应该重新呈现
  • 如果它不起作用......试试这个extraData={ this.state }
猜你喜欢
  • 2018-08-14
  • 1970-01-01
  • 1970-01-01
  • 2022-06-29
  • 2021-04-06
  • 1970-01-01
  • 2019-01-08
  • 1970-01-01
  • 2021-03-15
相关资源
最近更新 更多