Edit:
but I have to check for the presence of listRef
in the return function too, right?
Yes, and what you could do is wrap everythinig around the if statement
useEffect(() => {
// Everything around if statement
if (listRef && listRef.current) {
listRef.current.addEventListener(...)
return () => {
listRef.current.removeEventListener(...)
}
}
}, [listRef])
If you don't call addEventListener
, you don't need to call removeEventListener
, so that is why you put everything inside the if
.
You need to pass a function in the return that do what you want to do in the cleanup.
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(...)
}
}, [listRef])
return [listRef]
}
Another thing you need to notice is that inside the fooEventListener
, the ...
should be the same reference of the function, this means:
You shoudn't do this:
useEffect(() => {
if (listRef && listRef.current) {
listRef.current.addEventListener(() => console.log('do something'))
}
return () => {
listRef.current.removeEventListener(() => console.log('do something'))
}
})
And you should do :
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)
}
}, [listRef])
listRef
in the return function too, right? – Zacynthus