Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 不同的子组件通过同时调用setState来扰乱父组件的状态_Javascript_Reactjs_Setstate - Fatal编程技术网

Javascript 不同的子组件通过同时调用setState来扰乱父组件的状态

Javascript 不同的子组件通过同时调用setState来扰乱父组件的状态,javascript,reactjs,setstate,Javascript,Reactjs,Setstate,我正在创建一个基于间隔的游戏。父组件创建一个间隔,并允许其子组件注册每个间隔触发的回调 我的设置看起来像 <ParentComponent> <Child1 /> <Child2 /> ... </ParentComponent> 这种方法效果很好。但是现在我有两个孩子从componentDidMount()中调用registerCallback()方法 现在只有将其回调存储在父状态 当我延迟调用registerCallback()方

我正在创建一个基于间隔的游戏。父组件创建一个间隔,并允许其子组件注册每个间隔触发的回调

我的设置看起来像

<ParentComponent>
  <Child1 />
  <Child2 />
  ...
</ParentComponent>
这种方法效果很好。但是现在我有两个孩子从
componentDidMount()
中调用
registerCallback()
方法

现在只有
将其回调存储在父状态

当我延迟调用
registerCallback()
方法时

setTimeout(() => {
  registerCallback(callbackFunction, id)
}, 50 )
它工作得很好。但这感觉像是一个非常错误的黑客行为,特别是因为我需要“猜测”该州需要更新多长时间

所以我的结论是状态更新太慢了,而是在我的组件之外定义了一个数组并更新了它。奇怪的是,如果我对这个数组进行变异,它就可以正常工作

所以如果我使用
array.push({callback,id})
我的数组看起来像
[callback1,callback2]

但由于我不想改变我的数组,我尝试了
array.concat({callback,id})
这就给我留下了
[]

而我的状态看起来像
[array2]


如何改进父级中的方法,使子级能够在任何时候调用
registerCallback()
,而不会出现任何问题。

正如您正确推断的那样,问题是setState是异步的,因此当第二个子级调用registerCallback时,第一个子项的状态更改尚未传播到此.state。尝试:

registerCallback(回调,id){
this.setState(({callbacks})=>({
回调:callbacks.concat({
回拨,
身份证件
})
})
}

将函数作为第一个参数传递给setState。此函数接收当前状态(上面的解构为
{callbacks}
)并应返回新状态。该函数将立即调用,或在前一个状态更改传播时调用,因此其状态保证为新状态。因此,避免使用可能过时的
this.state

这里有一篇关于它的文章:


正如您正确推断的那样,问题在于setState是异步的,因此当第二个子调用registerCallback时,第一个子的状态更改尚未传播到此状态。请尝试:

registerCallback(回调,id){
this.setState(({callbacks})=>({
回调:callbacks.concat({
回拨,
身份证件
})
})
}

将函数作为第一个参数传递给setState。此函数接收当前状态(上面的解构为
{callbacks}
)并应返回新状态。该函数将立即调用,或在前一个状态更改传播时调用,因此其状态保证为新状态。因此,避免使用可能过时的
this.state

这里有一篇关于它的文章:


非常感谢。完美而优雅的答案。非常感谢。完美而优雅的答案。
setTimeout(() => {
  registerCallback(callbackFunction, id)
}, 50 )