我具有此功能:
addMessages(productId) {
const msg = "Some message about product: " + productId;
const newMessages = [...this.state.messages, msg];
console.log(this.state.messages);
this.setState({messages: newMessages}, function () {
console.log(newMessages);
console.log(this.state.messages);
});
}
我叫了两次
for (i = 700; i <= 701, i++) {
addMessages(i);
}
我得到此输出:
[]
[]
["Some message about product: 700"]
["Some message about product: 701"]
["Some message about product: 701"]
["Some message about product: 701"]
有人知道我的国家为什么这么奇怪吗?我最初了解它是一个空数组,并且它有机会进入回调函数之前,它在第一个控制台日志语句中运行了两次。但是为什么我的州没有达到700?为什么在通话之间将其清空?
发生的情况是由于setState
是异步的并且对批处理状态进行了响应。 React docs about setState
batching。
setState
回调之外的两个console.log
在循环期间立即执行。然后接下来的两个来自第一个setState
回调,最后两个来自第二个setState
回调。
它们的输出看起来奇怪的原因是,setState
实际上每次都不同,但是newMessages
已经在both回调中进行了更新。这样做的原因是由于批处理状态更新的方式。为了说明这一点,您可以在this.state.messages
函数内部进行控制台日志,并查看react仅触发了1次重新渲染以进行2个状态更新。
总而言之,React正在批处理您的render
,并且在所有循环更新发生后,两个回调都将被执行。
也请注意:由于要基于先前的值创建新的状态数组,因此应使用setStates
的更新程序形式。就目前而言,setState
将是每次迭代的空数组。
尝试此操作而不是在更新调用之外创建this.state.messages
:
newMessages
发生的情况是由于setState
是异步的并且对批处理状态进行了响应。 React docs about setState
batching。
setState
回调之外的两个console.log
正在立即执行。然后接下来的两个来自第一个setState
回调,最后两个来自第二个setState
回调。
看起来很奇怪的原因是因为setState
实际上每次都不同,但是newMessages
已在both回调中更新。这样做的原因是由于批处理状态更新的方式。为了说明这一点,您可以在this.state.messages
函数内部进行控制台日志,并查看react仅触发了1次重新渲染以进行2个状态更新。