Re-render child component on state change in parent component

I'm using react-navigation to navigate between two screens while passing data between them.

Flow: Screen A (passes data) -> Screen B -> (updates & passes data back) Screen A.

In Screen A, I'm using a child component which needs to be updated/re-rendered on receiving the data back from Screen B.

I've checked whether the data is being passed correctly and I'm positive that the state being used by the child component in the main screen is being updated. I just can't figure out why the child component isn't re-rendering after reading the new value of state?

Main Screen:

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} />

Component 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>

3 answers

  • answered 2019-03-13 18:37 lakerskill

    You will have to use componentDidUpdate with this. However, if you use hooks, that will knock out both the componentDidMount and componentDidUpdate. For your example with class based, it would probably be something along the lines of this.

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

    However, according to the docs, These methods are considered legacy and you should avoid them in new code:

    UNSAFE_componentWillMount()

    Drop that in favor of componentDidMount and componentDidUpdate, or switch to hooks (this is the best option!)

  • answered 2019-03-14 05:03 Amal p

    Update Component B:(Code below)

        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'})
                }
             }
    

    Include rest of your code.

    Study react lifecycle methods well.

  • answered 2019-03-14 16:20 Tushar Gupta

    Answering my question because I realized I was not updating the prop value in my component's code to reflect the change in state of the parent element.

    I guess that's why I was so confused in the first place because re-rendering on change of state is the CORE of React its workings. I used react-devtools to debug and figure out the lifecycle of my Child component. Everything works now! Not sure if I need hooks/other lifecycle methods for this simple functionality but I appreciate everyone's help!