根据docs中的解释:
setState()不会立即改变this.state,但会创建挂起状态转换 . 调用此方法后访问this.state可能会返回现有值 . 无法保证对setState的调用进行同步操作,并且可以对调用进行批处理以获得性能提升 .
因此, setState()
是异步的,并且无法保证其同步性能 . 是否存在同步的 setState()
替代方案 .
例如
//initial value of cnt:0
this.setState({cnt:this.state.cnt+1})
alert(this.state.cnt); //alert value:0
由于 alert
值是先前的值,因此使用 setState()
给出 alert value:1
的替代方法是什么 .
Stackoverflow上几乎没有问题类似于这个问题,但没有我能找到正确答案的地方 .
7 回答
正如您从文档中读到的那样,没有同步替代方案,所描述的原因是性能提升 .
但是我假设您想在更改状态后执行操作,可以通过以下方式实现:
不,那里没有 . React将在它认为合适时更新状态,执行诸如将
setState
调用一起进行批处理以提高效率 . 您可能感兴趣的是,您可以将一个函数传递给setState
,而该函数采用之前的状态,因此您可以选择具有前一个状态的新状态 .如果这是必需的,我建议在你的setState函数中使用回调(我还建议使用函数setState) .
状态更新后将调用回调 .
例如,你的例子就是
根据此处的文档:https://facebook.github.io/react/docs/react-component.html#setstate
注意:官方文档说,“通常我们建议使用componentDidUpdate()代替这种逻辑 . ”
是的,我们可以使用一种方法来创建同步setState . 但它的表现可能并不像通常那样好 . 例如,我们有
在此示例中,我们首先更改状态,然后渲染我们的组件 .
简短回答你的问题是 - 不,反应没有同步方法
setState
.您可以在返回promise的函数中包装setState,然后将此函数与await关键字一起使用,以使代码等到状态已应用 .
在foo函数中,
await
关键字导致代码执行暂停,直到setStateSynchronous
返回的promise已经解决,这只有在调用传递回setState
的回调时才会发生,这只有在应用了状态时才会发生 . 因此,一旦应用了状态更新,执行只会到达console.log调用 .async / await的文档:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
我能够通过将代码包装在_1462908中来欺骗React同步调用
setState
. 由于setTimeout
将东西放在JavaScript事件队列的末尾,我认为React检测到setState在其中,并且知道它不能依赖于批量的setState
调用(这将被添加到队列的末尾) .