如果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?这个组件没有真正目的,只是我正在尝试的东西
答案 0 :(得分:0)
让我们逐步介绍一下组件,看看实际发生了什么。我将用相应的渲染标记value和counter,以显示使用哪个版本(如value_1进行第一次重新渲染)。
value_0 = 0
,计数器_0 = 0
。
效果已运行。日志值_0。使用value_0注册清除。
使用value_0返回JSX。
1
。setCounter
值_1 = 0
,计数器_1 = 1
。
比较deps,[0]
元素与[1]
不同。运行清理。日志值_0。将值设置为1
。运行效果。日志值_1。使用value_1注册清除。
使用value_1返回JSX。
setValue
value_2 = 1
,counter_2 = 1
。
比较部门,[1]
个元素与[1]
匹配。
使用value_2返回JSX。
-
您会注意到,值和计数器是每个渲染的常量。毕竟它们被定义为const
。每当运行清理时,执行的函数就是最后一个渲染器返回的函数,该渲染器使用自己的value版本。
该效果永远不会在最后更新的结果上生效,因为deps并没有改变。
您可以通过使用react-hooks / exhaustive-deps皮棉规则来避免这种混淆。它将阻止您意外地在效果,回调或备注值中使用过时的值。