在useRef中传递null和undefined之间的区别

时间:2020-05-06 12:22:18

标签: javascript reactjs typescript 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)

当将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)
*/

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

从TypeScript类型看,这会产生什么影响?

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

2 个答案:

答案 0 :(得分:2)

之间没有任何区别
const undefinedRef: React.MutableRefObject<undefined> = useRef(undefined)
conse noArgRef: React.MutableRefObject<undefined> = useRef()

他们两个都有undefinedRef.currentnoArgRef.current未定义。

但是

const nullRef: React.MutableRefObject<null> = useRef(null)

nullRef.current分配为空

这将对您的代码产生唯一的影响,是当您实际尝试从当前内部访问属性或尝试检查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
}

答案 1 :(得分:1)

我相信类似const ref = useRef<SomeType>(null)这样的名称会使引用变为只读。

请参见this note from TypeScript cheatsheet

useRef存在重载,例如,如果您使用类型参数T vs T | null生成的对象是不同的:

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

第一个对象的当前属性是只读的 您,消费者。它应该作为指针传递给React 由React维护。实际上,您仍然可以更改当前 您传递给React的东西的属性,但不建议这样做 React应该是所有者。