Answer a question

I have built a simple counter app:

class Counter extends React.Component {

  constructor(props) {
    super(props);
    this.handleAddOne = this.handleAddOne.bind(this);
    this.handleMinusOne = this.handleMinusOne.bind(this);
    this.handleReset = this.handleReset.bind(this);
    this.state = {
      count: 0
    };
  }

  componentDidMount() {
      const stringCount = localStorage.getItem('count');
      const count = parseInt(stringCount);

      if (isNaN(count) === false) {
        this.setState(() => ({ count }));
      } 
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevState.count !== this.state.count) {
      localStorage.setItem('count', this.state.count);
      console.log('componentDidUpdate');
    }
  }

  handleAddOne() {
    this.setState((prevState) => {
      return {
        count: prevState.count + 1
      }
    });
  }
  
  handleMinusOne() {
    console.log('handleMinusOne');
    this.setState((prevState) => {
      return {
        count: prevState.count - 1
      }
    });
  }
  
  handleReset() {
    this.setState(() => {
      return {
        count: 0
      }
    });
  }

  render() {
    return (
      <div>
        <h1>Count: {this.state.count}</h1>
        <button onClick={this.handleAddOne}>+</button>
        <button onClick={this.handleMinusOne}>-1</button>
        <button onClick={this.handleReset}>reset</button>
      </div>
    );
  }
}

ReactDOM.render(<Counter />, document.getElementById('app'));

The question I have is with componentDidUpdate(). In it, I am checking to see if the prevState.count is not the same as the this.state.count. If it is not the same, then I set localStorage to the new count. If it is same, I do nothing.

In the current componentDidUpdate(), I need prevProps as an argument for this function to work correctly. For example, if I just have this:

componentDidUpdate(prevState) {
    if (prevState.count !== this.state.count) {
      localStorage.setItem('count', this.state.count);
      console.log('componentDidUpdate');
    }
  }

Then the component sets localStorage every time the reset button is pressed repeatedly, even though the count remains at 0.

What is going on? Why do I need prevProps for componentDidUpdate() to work correctly, if I am never using props in that function?

Answers

The first parameter in componentDidUpdate is prevProps. The second parameter is prevState. The documentation clearly states that:

componentDidUpdate(prevProps, prevState, snapshot)

This

componentDidUpdate(prevState) {...}

is not a correct signature for the hook. Even though the first parameter was called prevState, it contains previous props.

It's possible to alternate function parameters based on its arity but this isn't implemented in React and considered a bad practice in general because this leads to more complex signatures.

To not cause linter warnings, unused parameters can be underscored by convention:

componentDidUpdate(_prevProps, prevState) {...}
Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐