为什么在componentDidUpdate()中需要带有prevState的prevProps?

时间:2018-12-11 23:38:54

标签: reactjs

我建立了一个简单的柜台应用程序:

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

我的问题是componentDidUpdate()。在其中,我正在检查prevState.count是否与this.state.count不同。如果不相同,则将localStorage设置为新计数。如果不一样,我什么也不做。

在当前componentDidUpdate()中,我需要prevProps作为该函数正常工作的参数。例如,如果我只有这个:

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

然后,即使计数保持为0,每次重复按下重置按钮,组件也会设置localStorage

这是怎么回事?如果我从未在该函数中使用prevProps,为什么需要componentDidUpdate()才能使props正常工作?

3 个答案:

答案 0 :(得分:3)

是否在函数中使用prevProps并不重要,必须将其包括在内,因为函数中的参数顺序很重要。。

componentDidUpdate(prevProps, prevState)

如果您忽略prevProps参数,则prevState(即使名称会清楚地表明它是状态的先前版本)也将代表道具的先前版本。

这只是一个空白。您可以使用下划线来告诉其他人(或您自己)该功能未使用它。

componentDidUpdate(_, prevState)

答案 1 :(得分:2)

componentDidUpdate中的第一个参数是prevProps。第二个参数是prevStateThe documentation明确指出:

  

componentDidUpdate(prevProps,prevState,快照)

componentDidUpdate(prevState) {...}

不是该钩子的正确签名。即使第一个参数称为prevState,它也包含以前的道具。

可以根据参数的可变性来替换函数参数,但这在React中未实现,并且通常被认为是不好的做法,因为这会导致更复杂的签名。

为了不引起lint警告,可以通过约定对未使用的参数进行强调:

componentDidUpdate(_prevProps, prevState) {...}

答案 2 :(得分:1)

因为componentDidUpdate接收prevProps作为第一个参数,而prevState作为第二个参数。如果将函数编写为componentDidUpdate(prevState),它将接收prevProps,但是它将被命名为prevState。无论您如何命名参数,它们分别为prevPropsprevStatesnapshot

如果不需要第一个参数,则可以使用下划线,例如。 componentDidUpdate(_, prevState)