重新渲染后调用 ref 回调时,React 如何清除旧的 ref?

Cho*_*hor 7 reactjs react-hooks

正如 React 文档提到的

如果 ref 回调被定义为内联函数,则在更新期间它将被调用两次,第一次使用 null,然后再次使用 DOM 元素。这是因为每次渲染都会创建该函数的新实例,因此 React 需要清除旧的引用并设置新的引用。

我可以理解设置elnull,因为我们需要在重新渲染后释放旧 dom 节点的内存。但是,有两个问题我仍然无法弄清楚。

  1. 为什么 React 必须首先在这里调用旧的 ref 回调null?难道它不能用新的 dom 节点调用较新的 ref 回调吗?
  2. React 如何清除旧的引用?这与两次调用 ref 回调有关吗?

Jak*_*lek 3

您可以将回调 ref 的 ref 重置视为一种效果事实并非如此,但我认为重新表述问题确实有助于理解。

useEffect(() => {
  ref.current = element

  return () => {
    ref.current = null
  }
})
Run Code Online (Sandbox Code Playgroud)

假设您将 ref 回调传递给 DOM 节点:

<div ref={(element) => console.log(element)} />
Run Code Online (Sandbox Code Playgroud)

从效果的角度思考会给你带来:

  1. 当组件安装时,它会使用该元素调用 ref 回调
  2. 当组件卸载时,它会调用 ref 回调,null因为这是“清理”
  3. 当组件发生变化时,它首先调用“cleanup”,然后设置新的“effect”。

再次强调,这并不是说它使用了真正的 useEffect,但其背后的想法是相同的。