Javascript 函数内的React useffect stale值
在以下上下文中,如何更新函数Javascript 函数内的React useffect stale值,javascript,reactjs,sleep,staleobjectstate,Javascript,Reactjs,Sleep,Staleobjectstate,在以下上下文中,如何更新函数executeSimulation内部变量simulationOn的值: 应用程序此.state.simulationOn通过外部代码更改-->…-->React无状态组件(Robot)重新加载-->useEffect使用新值调用钩子-->executeSimulation未使用新值simulationOn更新 function Robot({ simulationOn, alreadyActivated, robotCommands }) {
executeSimulation
内部变量simulationOn
的值:
应用程序此.state.simulationOn
通过外部代码更改-->…-->React无状态组件(Robot
)重新加载-->useEffect
使用新值调用钩子-->executeSimulation
未使用新值simulationOn
更新
function Robot({ simulationOn, alreadyActivated, robotCommands }) {
useEffect(() => {
function executeSimulation(index, givenCommmands) {
index += 1;
if (index > givenCommmands.length || !simulationOn) {
return;
}
setTimeout(executeSimulation.bind({}, index, givenCommmands), 1050);
}
if (simulationOn && !alreadyActivated) {
executeSimulation(1, robotCommands);
}
}, [simulationOn, alreadyActivated, robotCommands]);
}
在上面的示例中,
simulationOn
从不更改为false
,即使使用更新的值调用useffect(我使用console.log检查)。我怀疑这是因为simulationOn
的新值从未传递到函数executeSimulation
的作用域,但我不知道如何在函数executeSimulation
内部传递新的钩子值,下面是演示陈旧关闭的代码:
var组件=测试=>{
log('调用组件',测试);
设置超时(
()=>console.log('test in callback:',test),
20
);
}
组件(真);
coponent(false)
executeSimulation函数有一个过时的闭包,simulationOn永远不会为true,下面是演示过时闭包的代码:
var组件=测试=>{
log('调用组件',测试);
设置超时(
()=>console.log('test in callback:',test),
20
);
}
组件(真);
组件(false)
simulationOn永远不会更改,因为父组件必须更改它。它将在属性中传递给此Robot组件。
我创建了一个沙盒示例来显示,如果在父级中正确更改它,它将向下传播。
这个机器人有几个设计问题。似乎假设机器人可以通过将索引值作为实例变量来“记住”索引值。React不是那样的。此外,它还假设当一个参数发生更改时,useEffect将只被调用一次,这是不正确的。我们不知道useEffect将被调用多少次。React仅保证在其中一个依赖项发生更改时调用它。但可以更频繁地调用它
我的示例显示,父级必须保留命令列表,并且需要发送完整的列表,以便哑机器人可以显示它执行的所有命令。simulationOn永远不会更改,因为父级组件必须更改它。它将在属性中传递给此Robot组件。 我创建了一个沙盒示例来显示,如果在父级中正确更改它,它将向下传播。 这个机器人有几个设计问题。似乎假设机器人可以通过将索引值作为实例变量来“记住”索引值。React不是那样的。此外,它还假设当一个参数发生更改时,useEffect将只被调用一次,这是不正确的。我们不知道useEffect将被调用多少次。React仅保证在其中一个依赖项发生更改时调用它。但可以更频繁地调用它
我的示例显示,父级必须保留一个命令列表,并且需要发送完整的列表,以便哑机器人可以显示它执行的所有命令。simulationOn在哪里更改?对不起,我刚才让问题更清楚了
this.state.simulationOn
通过外部代码更改应用程序类。我真的不明白问题出在哪一部分?如果要手动更改simulationOn,则必须将setSimulationOn回调一直传递到要更改它的组件。如果即使simulationOn=false,模拟仍然存在问题,那么问题可能是因为您没有清除setTimeout。我没有尝试手动更改simulationOn
,这已经发生了。我试图使函数executeSimulation
在运行时意识到对钩子变量所做的更改(特别是simulationOn
)。编辑:尝试清除setTimeout,但再次被忽略。为什么executeSimulation
必须在useEffect的范围内?如果希望它在每次超时时引用simulationOn
的当前值,则应在组件的范围内声明它,并直接引用该属性useEffect
有效地为该渲染和该渲染单独创建一个实例,不可能在其中传递任何新的道具-它们将始终传递到一个新实例。simulationOn在何处更改?抱歉,我刚才让问题更清楚了this.state.simulationOn
通过外部代码更改应用程序类。我真的不明白问题出在哪一部分?如果要手动更改simulationOn,则必须将setSimulationOn回调一直传递到要更改它的组件。如果即使simulationOn=false,模拟仍然存在问题,那么问题可能是因为您没有清除setTimeout。我没有尝试手动更改simulationOn
,这已经发生了。我试图使函数executeSimulation
在运行时意识到对钩子变量所做的更改(特别是simulationOn
)。编辑:尝试清除setTimeout,但再次被忽略。为什么executeSimulation
必须在useEffect的范围内?如果希望它在每次超时时引用simulationOn
的当前值,则应在组件的范围内声明它,并直接引用该属性useEffect
有效地为该渲染创建了一个实例,并且该渲染单独创建,不可能在其中传递任何新的道具-它们将始终传递给一个新实例。是的,感谢您指出问题并提供代码!这不会解决问题,因为每次更改道具时都会触发清除功能