Javascript 回调函数中调用之间的反应状态为空

Javascript 回调函数中调用之间的反应状态为空,javascript,reactjs,callback,state,Javascript,Reactjs,Callback,State,我有这个功能: 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 () {

我有这个功能:

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);
}

有人知道我的州为什么这么奇怪吗?我最初理解它是一个空数组,在有机会进入回调函数之前,它会在第一个控制台日志语句中运行两次。但为什么我所在的州得不到700美元?为什么在调用之间会被清空呢?

发生这种情况的原因是
setState
是异步的,并且响应批处理状态更新

在循环过程中,
setState
回调之外的两个
console.log
。接下来的两个来自第一个
setState
回调,最后两个来自第二个
setState
回调

它们的输出看起来奇怪的原因是
newMessages
实际上每次都不同,但是
this.state.messages
已经在两次回调中更新。这是由于如何反应批次状态更新。为了说明这一点,您可以在
render
函数中控制台日志,并查看react仅为2个状态更新触发了1个重新渲染

总之,React正在批处理您的
设置状态
,这两个回调都是在所有循环更新发生后执行的

另请注意:由于您是根据以前的值创建新的状态数组,因此应使用更新程序形式
setState
。目前,
this.state.messages
对于每次迭代都将是一个空数组。更新程序表单保证您将使用状态的最新副本进行更新

尝试此操作,而不是在更新调用之外创建
newMessages

this.setState(prevState=>({messages:[…prevState.messages,msg]}),/*callback*/)

从何处调用函数?你能提供一个代码沙盒来重现这个问题吗?或者编辑这个:它将运行700和701谢谢Brian,您不希望第二次迭代中的最后一个控制台日志语句在数组中同时包含两个字符串吗?
[“关于产品的一些消息:700”,“关于产品的一些消息:701”]
否,因为您正在使用
…this.state.messages
构建数组。由于它们是批处理的,
this.state.messages
对于这两个迭代都是
[]
。我会在我的回答中举例说明它是如何解决的!这很有道理,太棒了!成功了;非常感谢你!我以前从未听说过这件事,我在任何地方都看到并使用过我的代码。不过很有趣。
[]
[]
["Some message about product: 700"]
["Some message about product: 701"]
["Some message about product: 701"]
["Some message about product: 701"]