在 useRef 中传入 null 和 undefined 的区别

tor*_*kel 5 javascript typescript reactjs react-hooks

useRef(null)useRef(undefined)(或只是useRef())有什么区别?

在 TypeScript 中,结果以不同的类型结束:

const undefinedRef: React.MutableRefObject<undefined> = useRef(undefined)
conse noArgRef: React.MutableRefObject<undefined> = useRef()

const nullRef: React.MutableRefObject<null> = useRef(null)
Run Code Online (Sandbox Code Playgroud)

当将 ref 传递给另一个元素时,这也会产生进一步的后果:

const nullRef = useRef(null)
<div ref={nullRef} /> // this works

const undefinedRef = useRef()
<div ref={undefinedRef} /> // compiler failure!
/*
Type 'MutableRefObject<undefined>' is not assignable to type 'string | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
  Type 'MutableRefObject<undefined>' is not assignable to type 'RefObject<HTMLDivElement>'.
    Types of property 'current' are incompatible.
      Type 'undefined' is not assignable to type 'HTMLDivElement | null'.ts(2322)
*/
Run Code Online (Sandbox Code Playgroud)

尽管编译器失败,但它仍然适用于我的用例(使用useClickAway来自的钩子react-use

除了 TypeScript 类型之外,这有什么影响?

这是一个重现失败的 CodeSandbox:https ://codesandbox.io/s/prod-resonance-j9yuu?file =/ src/App.tsx

Shu*_*tri 5

之间没有任何区别

const undefinedRef: React.MutableRefObject<undefined> = useRef(undefined)
conse noArgRef: React.MutableRefObject<undefined> = useRef()
Run Code Online (Sandbox Code Playgroud)

它们都具有undefinedRef.currentnoArgRef.current未定义。

然而

const nullRef: React.MutableRefObject<null> = useRef(null)
Run Code Online (Sandbox Code Playgroud)

将被nullRef.current分配为 null

这对您的代码产生的唯一影响是当您实际尝试从 current 中访问属性或尝试检查 typeof ref 时

例如typeof nullRef.current将是object

和一个 if 条件,例如

if(typeof nullRef.current === "object") {
   // This will get executed only for nullRef and not for the other two refs
}
Run Code Online (Sandbox Code Playgroud)


zer*_*298 5

我相信类似的东西const ref = useRef<SomeType>(null)会使参考变成只读。

请参阅TypeScript 备忘单中的此注释

useRef 有重载,如果您使用类型参数 T 与 T | null 结果对象不同:

refObjectToPassIntoRefProp = useRef<HTMLDivElement>(null) // @type = {
current: HTMLDivElement | null } const refObjectYouMaintain =
useRef<HTMLDivElement | null>(null) // @type = { current:
HTMLDivElement | undefined } const refObjectYouMaintainToo =
useRef<HTMLDivElement>()
Run Code Online (Sandbox Code Playgroud)

对于第一个,对象的当前属性对您(消费者)来说是只读的。它应该被传递到 React,因为指针是由 React 维护的。在实践中,您仍然可以改变传递给 React 的当前属性,但不建议这样做,因为 React 应该是所有者。