Редактировать:
но я должен также проверить наличие 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)
}
})