reactjs 如果useEffect的回调包含一个未在其触发器数组中列出的状态变量,这是否会造成不一致?

quhf5bfb  于 2023-03-01  发布在  React
关注(0)|答案(1)|浏览(86)
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的过期值
zzlelutf

zzlelutf1#

简短回答:没有。
长回答:
React by it-self不包含魔法,也不修改JS语言,它只是使用它。让我们以实际为例:

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将返回当前值(如果没有人存在,则初始化为给定的initialValueundefined),该当前值是常数btw,以及setter函数。
  • useEffect将接受回调并执行它,如果给定的依赖性数组与前一次执行时(并且总是第一次调用它)有“浅的不同”。
  • 因为组件是在单个函数中定义的,所以呈现它的唯一方法就是调用它。

好了,现在我们已经清楚了基本概念,让我们考虑一下你想要修改一个状态,你调用它的setter函数:

set_is_mobile(true);

这个函数是由React提供的,所以我们不知 prop 体会发生什么,但我们可以想象:

  1. React将新值存储为某个内部数组或对象。
    1.它再次调用组件函数:是“重新渲染”。
    在这个新的渲染器上,调用了完全相同的useState()指令(这就是为什么总是以相同的顺序调用它们是如此重要),但是它返回新的值和相同的setter函数。其他状态没有改变,所以为它们返回相同的值。
    也调用了useEffect,但依赖关系数组相同(first值未更改),因此忽略回调。但是,如果调用了回调,则回调具有is_mobile的更新值。
    现在,您决定更新第二个状态set_first(true)。再次触发重新呈现,并发生完全相同的过程。第一个useState返回最新的first状态,第二个useState返回“不是新的但仍然是最新的”is_mobile状态。然后,调用useEffect,传递给它的回调函数总是有两个最新的值,但是这次,因为first的值发生了变化,所以React调用了回调函数,并且回调函数有所有最新的值。
    总结如下:
    useEffect的依赖项控制何时调用回调,但其中使用的每个值始终是最新的。
    我希望这是清楚的,并满足您对React状态和效果的理解!)

相关问题