为什么状态钩子中的值与useEffect中记录的值不同?

时间:2019-10-21 01:48:36

标签: javascript reactjs react-hooks

如果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?这个组件没有真正目的,只是我正在尝试的东西

1 个答案:

答案 0 :(得分:0)

让我们逐步介绍一下组件,看看实际发生了什么。我将用相应的渲染标记value和counter,以显示使用哪个版本(如value_1进行第一次重新渲染)。

挂载

value_0 = 0,计数器_0 = 0

效果已运行。日志值_0。使用value_0注册清除。

使用value_0返回JSX。

事件:用户点击增量。计数器设置为1

1。由setCounter

触发重新渲染

值_1 = 0,计数器_1 = 1

比较deps,[0]元素与[1]不同。运行清理。日志值_0。将值设置为1。运行效果。日志值_1。使用value_1注册清除。

使用value_1返回JSX。

2。由setValue

触发重新渲染

value_2 = 1,counter_2 = 1

比较部门,[1]个元素与[1]匹配。

使用value_2返回JSX。

-

您会注意到,值和计数器是每个渲染的常量。毕竟它们被定义为const。每当运行清理时,执行的函数就是最后一个渲染器返回的函数,该渲染器使用自己的value版本。

该效果永远不会在最后更新的结果上生效,因为deps并没有改变。

您可以通过使用react-hooks / exhaustive-deps皮棉规则来避免这种混淆。它将阻止您意外地在效果,回调或备注值中使用过时的值。