哪种方法在React中更新组件状态是合适的

时间:2019-11-11 18:59:56

标签: javascript reactjs ecmascript-6

这是CodePen中的工作example

它具有一个在ONOFF之间切换的按钮

React docs中,它使用prevState并更新了state的值。

    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));

当我使用以下方法时,它也会产生相同的结果。

    this.setState({isToggleOn: !this.state.isToggleOn})

有人可以建议哪种是更新{em> State Component的好方法吗?

2 个答案:

答案 0 :(得分:3)

由于setState的异步特性,建议不要使用this.state来获取setState中的先前状态。相反,如果必须使用以前的状态,请依靠updater function方法。

  

将setState()视为请求而非直接命令   更新组件。为了获得更好的感知性能,React可能会   延迟它,然后在一次通过中更新几个组件。反应   不保证状态更改会立即应用。   https://reactjs.org/docs/react-component.html#setstate

答案 1 :(得分:1)

就像其他人说的那样,您应该像在第一个示例中那样做。

prevState => ({isToggleOn: !prevState.isToggleOn})很少会产生与{isToggleOn: !this.state.isToggleOn}不同的结果,但是这种情况可能发生。

通常建议,每当您设置依赖于旧状态值的新状态时,始终使用更新程序功能。

以下两个片段演示了可能发生的情况:

将对象传递到setState

在这里,尽管使用setState将计数器增加了两次,但每次仅增加1。

class App extends React.Component {
  constructor() {
    super();
    this.state = {counter: 0};
    this.increment = this.increment.bind(this);
  }
  
  increment() {
    this.setState({counter: this.state.counter + 1});
    this.setState({counter: this.state.counter + 1});
  }
  
  render() {
    return (
      <div>
        <h3>{this.state.counter}</h3>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>


将函数传递给setState

在这里,计数器正确地增加了2。

class App extends React.Component {
  constructor() {
    super();
    this.state = {counter: 0};
    this.increment = this.increment.bind(this);
  }
  
  increment() {
    this.setState(prevState => ({counter: prevState.counter + 1}));
    this.setState(prevState => ({counter: prevState.counter + 1}));
  }
  
  render() {
    return (
      <div>
        <h3>{this.state.counter}</h3>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>