Разница между передачей null и undefined в useRef - PullRequest
2 голосов
/ 06 мая 2020

В чем разница между 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)

Это также имеет дальнейшие последствия при передаче ссылки другому элементу:

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 ]

1 голос
/ 06 мая 2020

Я считаю, что что-то вроде const ref = useRef<SomeType>(null) сделает ссылку только для чтения.

См. эту заметку из шпаргалки по TypeScript .

есть перегрузки для использования что если вы используете параметр типа 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 должен быть владельцем.

1 голос
/ 06 мая 2020

Нет никакой разницы между

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

оба они имеют undefinedRef.current и noArgRef.current как неопределенные.

Однако

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

будет иметь 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...