Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.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 函数内的React useffect stale值_Javascript_Reactjs_Sleep_Staleobjectstate - Fatal编程技术网

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
有效地为该渲染创建了一个实例,并且该渲染单独创建,不可能在其中传递任何新的道具-它们将始终传递给一个新实例。是的,感谢您指出问题并提供代码!这不会解决问题,因为每次更改道具时都会触发清除功能