为什么在React的#setState中使用函数解决了异步问题?

时间:2016-11-08 21:42:51

标签: javascript reactjs

docs开始,它说“React可以将多个setState()调用批处理为单个性能更新”,因此它建议使用函数而不是setState参数的对象。这是如何解决问题的?

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});

// Correct
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));

1 个答案:

答案 0 :(得分:6)

当你将一个对象传递给setState时,react将接受你传入的任何内容,创建一个事件来跟踪传入的内容,然后最终更新状态。正如文档所说,如果运行多个setStates,react可以将它们一起批处理,因为它将异步发生,也就是在某些时候,当你运行第一个例子时,它可能会使用实际的this.state.counter老了,引起意想不到的副作用。

第二个选项被认为更安全,因为它很像一个promise:当你传入一个函数时,React只会在状态实际更新后运行这个函数。这可以确保每次更新时都使用this.state.counter变量,并使用它们提供的prevState变量作为回调的参数。

我没有使用第一种方法遇到问题,但我也没有尝试过一次泛滥一堆setStates调用,我确信这是什么时候出现的。我看到这种犯规的主要方式是他们在设定状态后试图使用新状态。

例如:

increaseCounter() {
 this.setState({
   counter: this.state.counter + this.props.increment,
 });

 // this will more then likely be the previous value 
 // as setState does not run right away, but asynchronously 
 this.useNewCounter(this.state.counter) 
}

在该示例中,人们可能期望在调用useNewCounter时它将使用最新状态,但它不会,引用仍将指向前一个值,直到反应更新状态为止在调用此方法之后的某个时刻。