reactjs - Cách thêm một trình nghe sự kiện vào useRef trong useEffect
Tôi đang xây dựng một hook tùy chỉnh nơi tôi muốn thêm một trình lắng nghe sự kiện vào một ref, nhưng tôi không chắc cách dọn dẹp đúng cách, vì listRef và listRef.current có thể là 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]
}
Câu trả lời #1
Chỉnh sửa :
nhưng tôi cũng phải kiểm tra sự hiện diện của
listReftrong hàm trả về nữa, đúng không?
Vâng, và những gì bạn có thể làm là bao tất cả mọi thứ quanh câu lệnh if
useEffect(() => {
// Everything around if statement
if (listRef && listRef.current) {
listRef.current.addEventListener(...)
return () => {
listRef.current.removeEventListener(...)
}
}
}, [listRef])
Nếu bạn không gọi addEventListener, bạn không cần gọi removeEventListener, vì vậy đó là lý do tại sao bạn đặt mọi thứ bên trong if.
Bạn cần truyền một hàm trong phần trả về thực hiện điều bạn muốn làm trong việc dọn dẹp.
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]
}
Một điều khác bạn cần chú ý là bên trong fooEventListener, ... nên là cùng một tham chiếu của hàm, điều này có nghĩa là:
Bạn không nên làm điều này:
useEffect(() => {
if (listRef && listRef.current) {
listRef.current.addEventListener(() => console.log('do something'))
}
return () => {
listRef.current.removeEventListener(() => console.log('do something'))
}
})
Và bạn nên làm:
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])
