If the callback of a useEffect contains a state variable not listed in its trigger array, could this create an inconsistency?

huangapple go评论58阅读模式
英文:

If the callback of a useEffect contains a state variable not listed in its trigger array, could this create an inconsistency?

问题

const [first, set_first] = useState(false);
const [is_mobile, set_is_mobile] = useState(false);
useEffect(() => {
  if (!first) {
    window.scrollBy({ top: is_mobile ? -180 : -195 });
  }
}, [first]);

is_mobile不是useEffect的依赖项,但是它是回调函数的一部分。这可能会导致不一致性吗?

例如,

  • is_mobile被更改
  • useEffect未触发
  • first被更改。useEffect会使用is_mobile的过时值吗?
英文:
  const [first, set_first] = useState(false);
  const [is_mobile, set_is_mobile] = useState(false);
  useEffect(() => {
    if (!first) {
      window.scrollBy({ top: is_mobile ? -180 : -195 });
    }
  }, [first]);

is_mobile is not part of the useEffect's dependency, but is part of its callback. Could this potentially create an inconsistency?

For example,

  • is_mobile is changed
  • useEffect is not fired
  • first is changed. Will useEffect use the outdated value of is_mobile

答案1

得分: 2

简短回答:不。

长回答:

React 本身没有魔法,也不修改 JavaScript 语言,它只是使用它。让我们来实际分析一下你的例子:

  const [first, set_first] = useState(false);
  const [is_mobile, set_is_mobile] = useState(false);
  useEffect(() => {
    if (!first) {
      window.scrollBy({ top: is_mobile ? -180 : -195 });
    }
  }, [first]);

首先一些通用概念:

  • useState 将返回当前值(初始化为给定的 initialValue,如果没有提供则为 undefined),这是一个常量,以及一个设置器函数。

  • useEffect 将接受回调函数,并且只有在给定的依赖数组与上一次执行时的依赖数组 "浅层不同" 时才执行它(并且第一次始终调用)。

  • 因为你的组件在一个函数中定义,所以唯一的渲染方法是调用它。

现在,假设你想修改一个状态,你调用它的设置函数:

set_is_mobile(true);

这个函数是由 React 提供的,所以我们不知道确切发生了什么,但我们可以想象:

  1. React 在某个内部数组或对象中存储新值。
  2. 它再次调用组件函数:这是一次 "重新渲染"。

在这个新的渲染中,相同的 useState() 指令再次被调用(这就是为什么它们始终以相同的顺序被调用非常重要),但它返回新的值和相同的设置函数。其他状态没有改变,因此它们的值保持不变。

useEffect 也被调用,但依赖数组相同(first 值没有改变),因此回调被忽略。但是回调已经具有更新后的 is_mobile 值,如果它被调用的话。

现在,你决定更新第二个状态,set_first(true)。再次触发重新渲染,发生完全相同的过程。新的更新后的 first 状态由第一个 useState 返回,而 "不是新的但仍然更新后的" is_mobile 状态由第二个 useState 返回。然后,useEffect 也被调用,并且传递给它的回调函数具有两个更新后的值,与以往一样。但是这次,因为 first 的值已更改,React 调用了回调。并且它有所有更新后的值。

总结:

useEffect 的依赖项控制回调函数何时被调用,但在其中使用的每个值始终是最新的。

希望这些解释清楚并满足你对 React 状态和效果的理解! If the callback of a useEffect contains a state variable not listed in its trigger array, could this create an inconsistency?

英文:

Short answer: no.

Long answer:

React by it-self contains not magic and does not modify the JS language, it only uses it. Let's be practical and take your example:

  const [first, set_first] = useState(false);
  const [is_mobile, set_is_mobile] = useState(false);
  useEffect(() => {
    if (!first) {
      window.scrollBy({ top: is_mobile ? -180 : -195 });
    }
  }, [first]);

Some generic concept first:

  • useState will return the current value (initialized to the given initialValue or undefined if no one is present), which is a constant btw, and a setter function.

  • useEffect will take the callback and execute it if the dependency array given is "shallow different" than on the previous execution (and the first time it is always called).

  • Because your component is defined in a single function, the only way it could render it is to call it.

OK, now that we have made clear the basic concepts, let's consider you want to modify a state. You call its setter function:

set_is_mobile(true);

This function is provided by React, so we don't know exactly what happens, but we can imagine:

  1. React store the new value is some internal array or object.
  2. It calls the component function once again: It's a "re-render".

On this new render, the same exact useState() instruction is invoked (this is why it's so important for them to always be invoked in the same order), but it returns the new value, and the same setter function. The other states did not changed, so the same value is returned for them.

The useEffect is called too, but the dependency array is the same (first value did not changed) so the callback is ignored. However, the callback had the updated value for is_mobile, if it were invoked.

Now you decide to update the second state, set_first(true). Once again, a re-render is triggered, and the same exact process occurs. The newly up-to-date first state is returned by the first useState, and the "not-new-but-still-up-to-date" is_mobile state is returned by the second useState. Then, the useEffect is called, and the callback passed to it has the two up-to-date values, as always. But this time, because the value of first changed, the callback is being invoked by React. And it has all the up-to-date values.

To sum-up:

The dependencies of the useEffect controls when a callback is being invoked, but every values used inside are always up-to-date.

I hope this was clear and satisfies your comprehension about React states and effects! If the callback of a useEffect contains a state variable not listed in its trigger array, could this create an inconsistency?

huangapple
  • 本文由 发表于 2023年2月27日 05:26:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575112.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定