简体   繁体   English

传入 null 和 undefined in useRef 之间的区别

[英]Difference between passing in null and undefined in useRef

What's the difference between useRef(null) and useRef(undefined) (or just useRef() )? useRef(null)useRef(undefined) (或只是useRef() )有什么区别?

In TypeScript, the results end up with different types:在 TypeScript 中,结果以不同的类型结束:

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

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

This also has further consequences, when passing the ref to another element:当将 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)
*/

Despite the compiler failure, it still works for my use case (using the useClickAway hook from react-use )尽管编译器失败,它仍然适用于我的用例(使用react-use中的useClickAway挂钩)

What's the impact at this, looking beyond the TypeScript types?除了 TypeScript 类型之外,这有什么影响?

Here's a CodeSandbox that recreates the failure:https://codesandbox.io/s/prod-resonance-j9yuu?file=/src/App.tsx这是重现故障的 CodeSandbox:https://codesandbox.io/s/prod-resonance-j9yuu?file=/src/App.tsx

There isn't any difference between之间没有任何区别

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

both of them have undefinedRef.current and noArgRef.current as undefined.他们都有未定义的undefinedRef.currentnoArgRef.current

However然而

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

will have nullRef.current assigned as nullnullRef.current分配为 null

The only impact this will have in your code is when you actually try to access a property from within current or try to check the typeof ref这将对您的代码产生的唯一影响是当您实际尝试从 current 中访问属性或尝试检查 typeof ref

For instance typeof nullRef.current will be object例如typeof nullRef.current将是object

and an if condition like和一个 if 条件

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

I believe something like const ref = useRef<SomeType>(null) will make the reference readonly.我相信像const ref = useRef<SomeType>(null)这样的东西会使参考只读。

See this note from TypeScript cheatsheet .请参阅TypeScript 备忘单中的此注释

there are overloads for useRef such that if you use a type param T vs T | useRef 有重载,因此如果您使用类型参数 T vs T | null the resultant object is different: null 结果 object 是不同的:

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

With the first, the current property of the object is read-only to you, the consumer.首先,object 的当前属性对您(消费者)是只读的。 It's meant to be passed into React as the pointer is maintained by React.当指针由 React 维护时,它应该被传递给 React。 In practice, you can still mutate the current property of something you pass into React but it's not recommended as React is supposed to be the owner.在实践中,你仍然可以改变你传递给 React 的东西的当前属性,但不建议这样做,因为 React 应该是所有者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM