如果useEffect在渲染阶段之后运行,为什么我在useEffect中的值小于返回中显示的值?
我有一个组件,每当我的计数器在清理时发生变化时,它就会更新value
const [value, setValue] = useState(0);
const [counter, setCounter] = useState(0);
useEffect(() => {
console.log(`value = ${value} from effect`);
return () => {
setValue(v => v + 1);
console.log(`value = ${value} from cleanup`);
};
}, [counter]);
return (
<div>
<button onClick={() => setCounter(v => v + 1)}>Increment Counter</button>
<p>value: {value}</p>
</div>
);
在第一次增量中,我的返回中的value
将为 1,但我的 useEffect 会将其记录为 0。为什么这些值会有所不同,为什么 useEffect 不会记录 1?这个组件没有真正的用途,只是我正在试验的东西
让我们逐步完成您的组件,看看实际发生了什么。我将用它们各自的渲染来标记值和计数器,以显示使用哪个版本,例如value_1第一次重新渲染。
安装
value_0 =0
, counter_0 =0
。
效果已运行.log value_0. 使用 value_0 进行注册清理。
使用 value_0 返回 JSX。
事件:用户单击递增。计数器设置为1
。
1.setCounter
触发的重新渲染
value_1 =0
, counter_1 =1
。
比较部门,[0]
元素与[1]
不同。运行清理。日志value_0。将值设置为1
。效果已运行。日志value_1。使用 value_1 注册清理。
使用 value_1 返回 JSX。
2.setValue
触发的重新渲染
value_2 =1
, counter_2 =1
。
比较部门,[1]
元素匹配[1]
。
使用 value_2 返回 JSX。
-
您会注意到值和计数器是每个渲染的常量。毕竟,它们被定义为const
。每当运行清理时,执行的函数都是最后一个渲染返回的函数,该渲染使用自己的值版本。
该效果永远不会在值最终更新时运行,因为 deps 没有更改。
您可以通过使用 react-hooks/exhaustive-deps lint 规则来避免这种混淆。它将阻止您在效果、回调或记忆值中意外使用过时的值。