Как добавить слушатель события в useRef в useEffect - PullRequest
1 голос
/ 03 марта 2020

Я создаю пользовательский хук, в котором я хочу добавить прослушиватель событий в ссылку, но я не уверен, как правильно его очистить, поскольку listRef и listRef.current могут иметь значение null:

export const myHook: MyHook = () => {
  const listRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    // I can check for the presence of `listRef.current` here ...
    if (listRef && listRef.current) {
      listRef.current.addEventListener(...)
    }

    // ... but what's the right way for the return function?
    return listRef.current.removeEventListener(...)
  })

  return [listRef]
}

1 Ответ

2 голосов
/ 03 марта 2020

Редактировать:

но я должен также проверить наличие listRef в функции возврата, верно?

Да, и что вы можете сделать это обернуть все вокруг оператора if

  useEffect(() => {
    // Everything around if statement
    if (listRef && listRef.current) {
      listRef.current.addEventListener(...)

      return () => {
        listRef.current.removeEventListener(...)
      }
    }
  })

Если вы не вызываете addEventListener, вам не нужно вызывать removeEventListener, поэтому вы помещаете все в if.


Вам нужно передать в возврате функцию, которая делает то, что вы хотите сделать при очистке.

export const myHook: MyHook = () => {
  const listRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    // This is ok
    if (listRef && listRef.current) {
      listRef.current.addEventListener(...)
    }

    // Passing a function that calls your function
    return () => {
        listRef.current.removeEventListener(...)
    }
  })

  return [listRef]
}

Еще одна вещь, которую вы должны заметить, это то, что внутри fooEventListener, ... должен быть тем же эталоном функции, это означает:

Вы не должны этого делать:

  useEffect(() => {
    if (listRef && listRef.current) {
      listRef.current.addEventListener(() => console.log('do something'))
    }

    return () => {
        listRef.current.removeEventListener(() => console.log('do something'))
    }
  })

И вы должны сделать:

  useEffect(() => {
    const myFunction = () => console.log('do something')

    if (listRef && listRef.current) {
      // Passing the same reference
      listRef.current.addEventListener(myFunction)
    }

    return () => {
      // Passing the same reference
      listRef.current.removeEventListener(myFunction)
    }
  })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...