为什么 React `useRef` 钩子将对象存储在 `current` 属性中?为什么不能直接存储在 ref 对象中?

Joh*_*ian 8 javascript reactjs react-hooks

为什么useRef钩子返回的对象存储它应该在current属性中保存的任何值?为什么我们不能直接给 ref 对象赋值,如下所示:

const sampleRef = useRef([]);

/** why can't we do this... */
sampleRef.push('1');

/** ...instead of this? Why an extra `current` object? */
sampleRef.current.pus('1');
Run Code Online (Sandbox Code Playgroud)

useRef返回包装在另一个具有属性的对象中的参数的目的是什么current

mea*_*dre 8

这个问题的答案并不特定于 React 及其钩子系统。改变对象只是如何在不同闭包/作用域之间共享值的解决方案。

当您调用useRef()组件时,React 内部会创建一个“ref 对象”,该对象与组件的特定实例相关联。每次useRef()在多个渲染中调用时,都会返回相同的“ref 对象”。对它的设置current是您存储值以便在下次渲染时重新访问它的方式。

通过做类似的事情

let value = useRef();
value = 1234;
Run Code Online (Sandbox Code Playgroud)

您将丢弃 ref 对象,并将其替换为本地范围内的新值。React 无法跟踪该操作并更新存储在其内部的 ref 对象。(事实上​​,React 无论如何都不会跟踪对“ref 对象”的任何操作,它只是将它们提供给你。你改变它们,你访问它们)。

但使用当前的 API,您可以

const ref = useRef(); // ref is an object that is stored somewhere in React internals
ref.current = 1234; // you update the property of that object
Run Code Online (Sandbox Code Playgroud)

下次组件渲染时,React 会为您提供相同的 ref 对象,以便您可以使用之前设置的值。


Ali*_*rki 2

据我了解,他们之所以这样做是因为他们需要创建一个对象来密封DOM 元素对象(在开发模式下)并记住它。如您所知,如果我们要记住某些内容,我们需要将其转换为对象数组

参考:


function mountRef<T>(initialValue: T): {current: T} {
  const hook = mountWorkInProgressHook();
  const ref = {current: initialValue};
  if (__DEV__) {
    Object.seal(ref);
  }
  hook.memoizedState = ref;
  return ref;
}
Run Code Online (Sandbox Code Playgroud)

https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberHooks.js#L916