React 的 setState 方法与 prevState 参数

27 javascript reactjs

我是 React 的新手,只是对 setState 方法有疑问。假设我们有一个组件:

class MyApp extends React.Component {

  state = {
    count: 3
  };

  Increment = () => {
    this.setState((prevState) => ({
      options: prevState.count + 1)
    }));
  }
}
Run Code Online (Sandbox Code Playgroud)

那么为什么我们必须在 setState 方法中使用 prevState 呢?为什么我们不能这样做:

this.setState(() => ({
  options: this.state.count + 1)
}));
Run Code Online (Sandbox Code Playgroud)

Dup*_*cas 23

两种签名都可以使用,唯一的区别是如果你需要根据之前的状态改变你的状态,你应该使用this.setState(function)它会为你提供prevState之前状态的快照()。但如果更改不依赖于任何其他先前的值,则建议使用较短的版本this.setState({prop: newValue})

this.setState(prevState =>{
   return{
        ...prevState,
        counter : prevState.counter +1
   }
})

this.setState({counter : 2})
Run Code Online (Sandbox Code Playgroud)

  • 不要做`prevState.counter++`,因为这会改变`prevState`。改为执行`prevState.counter + 1`。 (2认同)
  • 我只是说这是一个不好的做法。我自己过去也犯过同样的错误,并且遇到过问题。 (2认同)

小智 13

class MyApp extends React.Component {

  state = {
    count: 0
  };

  Increment = () => {
    this.setState(prevState => ({
      count: prevState.count + 1
    }));
    this.setState(prevState => ({
      count: prevState.count + 1
    }));
    this.setState(prevState => ({
      count: prevState.count + 1
    }));
    this.setState(prevState => ({
      count: prevState.count + 1
    }));
  };

  IncrementWithoutPrevState = () => {
    this.setState(() => ({
      count: this.state.count + 1
    }));
    this.setState(() => ({
      count: this.state.count + 1
    }));
    this.setState(() => ({
      count: this.state.count + 1
    }));
    this.setState(() => ({
      count: this.state.count + 1
    }));
  };

  render() {
    return (
      <div>
        <button onClick={this.IncrementWithoutPrevState}>
          Increment 4 times without PrevState
        </button>
        <button onClick={this.Increment}>
          Increment 4 times with PrevState
        </button>
        <h1>Count: {this.state.count}</h1>
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

我只是举了一个例子让你了解“React 可以批处理多个 setState()...”的含义以及为什么我们应该在上述场景中使用 prevState。

首先,试着猜测Count当你同时点击两个按钮时会产生什么结果......如果你认为点击两个按钮count都会增加 4,那么这不是正确的猜测;)

为什么?因为IncrementWithoutPrevState方法,因为有多个setState电话,等反应过来批量所有这些电话,并更新state只在最后调用setState这个方法,所以在最后一次通话的时间,setState在这个方法this.state.count还没有被更新,其价值仍然是相同的那是在进入IncrementWithoutPrevState方法之前,因此结果状态将包含count递增 1。

现在另一方面,如果我们分析该Increment方法: 再次有多个setState调用并且 React 将它们全部批处理,这意味着实际状态将在最后一次调用中更新,setStateprevState将始终包含state在最近setState调用中修改的状态。由于previousState.count值已经增加了 3 次,直到最后一次调用,setState因此结果state将包含增加了 4 的计数值。