简体   繁体   English

为什么我在 state 挂钩中的值与我在 useEffect 中登录的值不同?

[英]Why is my value from state hook different than what I'm logging in my useEffect?

If useEffect runs after the render phase, why is my value in useEffect less than what is being shown in the return?如果 useEffect 在渲染阶段之后运行,为什么我在 useEffect 中的值小于返回中显示的值?

I have a component that will update value whenever my counter changes on cleanup我有一个组件,只要我的计数器在清理时发生变化,它就会更新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>
  );

On first increment, the value in my return will be 1, but my useEffect will log it as 0. Why would those values be different and why would the useEffect not log 1 as well?在第一次递增时,我返回的value 1,但我的 useEffect 会将其记录为 0。为什么这些值会不同,为什么 useEffect 也不会记录 1? This component doesn't have a real purpose, just something I'm experimenting with这个组件没有真正的用途,只是我正在试验的东西

Simply because setValue() is async and your effect only has counter as dependency.仅仅因为setValue()是异步的,并且您的效果仅具有counter作为依赖项。

Meaning your effect will only run every counter change only and not every value changes.这意味着您的效果只会运行每个counter更改,而不是每个value都会更改。

To capture every value changes, add another effect with value as dep:要捕获每个value的变化,请添加另一个具有value作为 dep 的效果:

useEffect(() => console.log(value), [value])

Other factor affecting the delay is due to when effect cleanup is called.影响延迟的其他因素是由于何时调用效果清理。

From useEffect :useEffect

React cleans up effects from the previous render before running the effects next time. React 会在下次运行效果之前清理上一次渲染的效果。

Let's step through your component and look at what's actually happening.让我们逐步检查您的组件,看看实际发生了什么。 I will mark value and counter with their respective render to show which version is used like value_1 for first rerender.我将用各自的渲染标记 value 和 counter 以显示使用哪个版本,如 value_1 用于第一次重新渲染。

Mount

value_0 = 0 , counter_0 = 0 . value_0 = 0 ,counter_0 = 0

Effect is run.运行效果。 log value_0.记录值_0。 register cleanup using value_0.使用 value_0 进行寄存器清理。

return JSX using value_0.使用 value_0 返回 JSX。

Event: user clicks increment.事件:用户点击增量。 counter is set to 1 .计数器设置为1

1. rerender triggered by setCounter 1. setCounter触发重新渲染

value_1 = 0 , counter_1 = 1 . value_1 = 0 ,counter_1 = 1

Compare deps, [0] elements differ from [1] .比较 deps, [0]元素不同于[1] Cleanup is run.运行清理。 log value_0.记录值_0。 set value to 1 .将值设置为1 Effect is run.运行效果。 log value_1.记录值_1。 register cleanup using value_1.使用 value_1 进行寄存器清理。

return JSX using value_1.使用 value_1 返回 JSX。

2. rerender triggered by setValue 2. setValue触发重新渲染

value_2 = 1 , counter_2 = 1 . value_2 = 1 ,counter_2 = 1

Compare deps, [1] elements match [1] .比较 deps, [1]元素匹配[1]

return JSX using value_2.使用 value_2 返回 JSX。

- -

You will notice that value and counter are constants for each render.您会注意到 value 和 counter 对于每个渲染都是常量。 They are defined as const after all.毕竟它们被定义为const Whenever cleanup is run, the function that is executed is the one returned by the last render, which used its own version of value.每当运行清理时,执行的 function 是最后一个渲染返回的,它使用自己的值版本。

The effect is never run on the last update where value is finally up to date because the deps haven't changed.效果永远不会在最后一次更新时运行,因为 deps 没有改变,所以值最终是最新的。

You can avoid this kind of confusion by using the react-hooks/exhaustive-deps lint rule.您可以通过使用 react-hooks/exhaustive-deps lint 规则来避免这种混淆。 It will stop you accidentally using out-of-date values in your effects, callbacks or memoised values.它会阻止您在效果、回调或记忆值中意外使用过时的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我不能从当前的 state 中获取一个值并在我的 useState 挂钩中使用它? - Why cant I take a value from the current state and use that inside of my useState hook? 为什么即使在 UseEffect 挂钩中设置状态后我的 React 状态仍未定义? - Why is my React state undefined even after setting the state in UseEffect hook? 如何在数组依赖中正确使用 useEffect 钩子。 我从 redux 商店传递了状态,但我的组件仍然无限渲染 - How to use useEffect hook properly with array dependency. I passed state from redux store and still my component renders infinitely 当 State 在 ReactJS 中的不同 .js 文件的组件中发生更改时,如何更新我的 useEffect 挂钩? - How to update my useEffect hook when State change happen in a different .js file's component in ReactJS? 为什么我不能在 useEffect 回调中更新我的组件的 state? - Why can't I update the state of my component from within a useEffect callback? 为什么我的状态没有在 useEffect 中更新? - Why is my state not updating inside useEffect? useEffect 中的 Why.then() 没有更新我的 state - Why .then() which is in useEffect is not updating my state 为什么更新反应上下文值时我的 useEffect() 不会触发? - Why won't my useEffect() hook fire when updating a react context value? State 未从 useEffect 挂钩更新 - State not updating from useEffect hook 为什么我在 React 中的钩子变量没有保持我设置的状态? - Why is my hook variable in React not holding the state I set it to?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM