T
T
The_good_game2021-07-03 16:34:44
JavaScript
The_good_game, 2021-07-03 16:34:44

How does the componentDidUpdate function work?

I'm just learning React and I can't figure out the behavior of the React function. Let's say I have 2 components: parent and child.

class App extends React.Component {
  constructor(props) {
    super(props);

    this.value = '';
  }
  render() {
    return (
      <div className="App">
  
        <input onChange={(e) => {
          this.value = e.target.value
        }}></input>
        <button onClick={() => {
          this.setState({value: this.value})
        }}>Send</button>
  
      {this.state && <Child newValue={this.state.value}/>}
      </div>
    );
  }
}

class Child extends React.Component {
  constructor(props) {
    super(props);

    this.value = null;
  }

  componentDidUpdate(prevProps, prevState) {
    console.log('prevState')
    console.log(prevState);
    console.log('this.state')
    console.log(this.state)
    if (prevState === this.state) {
      this.setState({value: this.props.newValue})
    }
  }

  render() {
    return (
      <div>
        Hello!
      </div>
    )
  }
}


When the button is clicked, the parent component updates its state and re-renders the child component. But I don't understand at all why the condition (prevState === this.state) is fulfilled here for correct operation, and not (prevState !== this.state). Console output:

// я ввёл в поле инпут единицу и нажал два раза button
// так как в первый раз дочерний элемент только монтируется, 
// а обновляется только при втором нажатии
prevState
null
this.state
null
prevState
null
this.state
{value: "1"}

// эти выводы покажутся, если я введу 12 и нажму button
prevState  
{value: "1"}  // почему здесь выводится значение {value: "1"}, а не null? 
              // Ведь изменение состояния не было.
this.state
{value: "1"}
prevState
{value: "1"}
this.state
{value: "12"}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey, 2021-07-04
@The_good_game

  1. You entered "1", pressed the button: the state of the parent changes to {value: "1"} , the Child is updated for the first time
  2. componentDidUpdate doesn't fire on the first render, so Child just displays Hello!
  3. The input is still "1", you pressed the button a second time. SetState is called again with {value: "1"} , but each call to setState causes the component to be re-rendered, so after the second click, the parent is updated, followed by the child
  4. On the second re-render, componentDidUpdate is triggered for Child , and since the state in the child is undefined, i.e. by default is null , then the condition in if in componentDidUpdate is triggered
  5. Child updates its state and writes {value: "1"} there , after that it is updated again, but since now the previous state was null , and the current one is {value: "1"} , then the if condition in componentDidUpdate is no longer true
  6. Add the number "2" in the input, press the button. Parent changes state to {value: "12"} and updates with child
  7. And then the answer to your question: Child again after the update, componentDidUpdate fires . At the same time, the previous value in his state remains what was written in paragraph 5 and the current one is also equal to the same value, i.e. in this case, if will work again and the state will change to {value: "12"} in Child
  8. Child is updated again after changing its state, componentDidUpdate fires , the previous state value outputs "1" and the current one is already "12" so the if fails again

I hope I wrote it clearly) It’s not clear why you need a state in Child that duplicates props, you don’t need to do that

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question