【问题标题】:Re-render child component on state change in parent component在父组件的状态更改时重新渲染子组件
【发布时间】:2019-03-13 18:29:27
【问题描述】:

我使用react-navigation 在两个屏幕之间导航,同时在它们之间传递数据。

流程: 屏幕 A(传递数据)-> 屏幕 B ->(更新并传回数据)屏幕 A。

在屏幕 A 中,我正在使用一个子组件,在从屏幕 B 接收到数据时需要对其进行更新/重新渲染。

我检查了数据是否正确传递,并且我确信主屏幕中子组件正在使用的状态正在更新。我只是想不通为什么在读取 state 的新值后子组件没有重新渲染?

主屏幕:

updateCount(data) {
    // Logic to update state of a counter variable
    this.setState({ count: data })
}

// and then later on in the code, I'm calling the child Component 'B'        
<B prop={this.state.count} />

组件 B:

componentWillMount() {
// based on value of this.props.count, I'm setting the value of 'text' in this component
    if(this.props.count == 1) {
       this.setState({text: 'abc'})
    } else {
       this.setState({text: 'cde'})
    }
}

// later on in the code, render method:
<View>
   <Text>
     {this.state.text}
   </Text>
</View>

【问题讨论】:

  • 尝试将 componentWillMount 更改为 componentDidMount。另外,你能创建一个codesandbox吗?

标签: reactjs react-native react-navigation


【解决方案1】:

更新组件 B:(代码如下)

    constructor(props) {
            super(props);
            this.state = {
                count: props.count
            };
         }

        componentWillReceiveProps(nextProps) {
           if (nextProps.count != this.props.count){
                this.setState({
                count: nextProps.count
            })
          }
        }

       componentDidMount() {
             this.setTextValue();
       }

         componentWillUpdate() {
             this.setTextValue();
       }

         setTextValue = () => {
           if(this.state.count == 1) {
               this.setState({text: 'abc'})
           } else {
              this.setState({text: 'cde'})
            }
         }

包含您的其余代码。

学习反应lifecycle methods

【讨论】:

    【解决方案2】:

    回答我的问题是因为我意识到我没有更新组件代码中的 prop 值以反映父元素状态的变化。

    我想这就是我一开始如此困惑的原因,因为在状态变化时重新渲染是 React 工作的核心。我使用react-devtools 来调试并找出我的子组件的生命周期。现在一切正常!不确定我是否需要钩子/其他生命周期方法来实现这个简单的功能,但我感谢大家的帮助!

    【讨论】:

      【解决方案3】:

      您将不得不使用 componentDidUpdate 。但是,如果您使用钩子,则会同时破坏 componentDidMount 和 componentDidUpdate。对于您的基于类的示例,它可能与此类似。

          componentdidUpdate(prevProps, props) => {
            if(prevProps.count !== this.props.count){
          if(this.props.count == 1) {
            this.setState({text: 'abc'})
             }
              else {
           this.setState({text: 'cde'})
            }}
      

      但是,根据文档,这些方法被认为是遗留的,您应该在新代码中避免使用它们:

      UNSAFE_componentWillMount()

      放弃它以支持 componentDidMount 和 componentDidUpdate,或者切换到 hooks(这是最好的选择!)

      【讨论】:

      • 我确实认为 componentWillMount 是不安全的,所以我真的不知道我是如何推荐任何遗留的东西的? componentDidMount 和 componentDidUpdate 都不是旧版,那么我推荐哪种旧版方法?
      • 另外,我推荐使用一个钩子,它刚刚出来吗?
      • 我的错,我误读了你最初所说的内容。 getDerivedStateFromProps 方法仍应充分考虑,因为它是最可靠的方法,但建议您使用钩子也可以。
      • 一切顺利!我的措辞也很糟糕,所以不仅仅是你。老实说,在这一点上,使用钩子要干净得多。
      猜你喜欢
      • 2021-04-06
      • 1970-01-01
      • 2022-06-29
      • 1970-01-01
      • 2020-12-30
      • 2019-09-21
      • 2018-08-14
      • 1970-01-01
      • 2019-01-08
      相关资源
      最近更新 更多