我正在构建一段代码,其中需要两个嵌套组件来更新状态变量:
function Test() {
const [test, setTest] = useState()
async function wait() {
await new Promise((res, rej) => setTimeout(res, 1000))
console.log("after 1s waiting, test is", test)
}
async function setTest1() {
await wait()
setTest("test1")
}
async function setTest2() {
setTest("test2")
}
useEffect(() => console.log("after being updated, test is", test), [test]);
return (
<div>
<div onClick={setTest1}>
<span onClick={setTest2}>update test</span>
</div>
</div>
)
}
当点击";"更新测试";,则调用CCD_ 1,然后调用setTest1
。这是异步发生的:setTest1
可能在setTest2
结束之前被调用。
首先,调用setTest2
和setTest1
。然后setTest2
更新test
,赋予其值"test2"
。此时setTest2
0仍在运行。它正在等待1秒才能继续。在1s之后,test
的值无疑是"test2"
。不是吗?。。。
当在等待1秒后记录test
的值时,我希望结果是"test2"
,因为状态已经更新为"test2"
。然而,结果不是"test2"
,而是undefined
,就好像它没有被setTest2
更新一样。
这段代码记录如下:
after being updated, test is undefined
after being updated, test is test2
after 1s waiting, test is undefined <--- what ???
after being updated, test is test1
这看起来像是某种范围界定机制,但我找不到对此的解释
在setTest1
调用内部登录wait
调用时,为什么test
的值不是test2
?
因为"等待";被添加到调用堆栈;等待";创建。
- 步骤1:启动应用程序时,UseEffect首先运行=>quot;如果在被更新之后测试是未定义的">
- 步骤2:当您单击=>同时调用了setTest1和setTest2。但是";等待";在步骤1中声明;测试";"内部";等待";未定义,因此在setTest2((完成后=>quot;在被更新之后测试是test2",则setTest1((完成=>quot;等待1s后,测试未定义"=>quot;更新后的测试为test1">
如果再次单击。结果将是:
----更新后,test为test2。
----等待1s后,测试为test1。
----更新后,test为test1。
因为";等待";被重新声明,并且";测试";"内部";等待";是";test1";。
希望这能让你明白。一些更新更清楚:
每次调用setState时;测试";用新值创建(不将新值分配给当前的"测试"(;等待";仍然指旧的";测试"===>所以这就是为什么;未定义的";第一次点击。