我偶然发现了一个对我来说非常奇怪的问题,但很可能很容易解释。演示让我们假设以下 React 组件import React, { useState, useEffect, useCallback } from "react";export default function App() { const [test, setTest] = useState(); const doSomething = () => { // TODO: Why does this returns the inital state value? Hoisting? console.log(test); }; const doSomethingWithCallback = useCallback(doSomething, [test]); useEffect(() => { setTest("asas"); window.setTimeout(() => doSomething(), 2000); document.addEventListener("click", doSomethingWithCallback); return () => { document.removeEventListener("click", doSomethingWithCallback); }; }, [doSomethingWithCallback]); return ( <div className="App"> <h1>Click anywhere</h1> </div> );}(参见CodeSandbox)问题看一下TODO代码中的注释。为什么控制台会记录最初设置的doSomething状态,即回调变体在调用时返回“真实”当前状态?testundefined这是 React 正在做的某种提升或性能优化吗?
1 回答
拉莫斯之舞
TA贡献1820条经验 获得超10个赞
这和吊装没有太大关系。setTest
正在导致重新渲染,这将导致useCallback
评估它的回调,因为它的依赖项发生了变化。
解释为什么另一个函数调用返回初始值有点神秘,但我认为这与您注册调用时的 test 值有关setTimeout
。
AnysetState
是异步的,如果您设置状态然后同步尝试立即引用状态,则不能保证状态中的值与您期望的值一致。相反,它很可能不会,我没有完全了解,但我相信在同步工作队列完全为空之前或多或少不会完成任何异步工作。
至于你的实际问题,“国家价值观是否被提升?” 是的,就像 Javascript 中的所有值一样。然而,反应状态钩子值略有不同,因为它们的执行顺序在渲染之间必须始终相同,因此您必须至少保持那么多(即可能不存在条件钩子实例化)。
添加回答
举报
0/150
提交
取消