我尝试了以下 2 种方法来删除事件处理程序,但似乎都不起作用
解决方案 1:
const keyBindSearch = useCallback(e => {
if ((e.metaKey && e.key === 'f') || (e.ctrlKey && e.key === 'f')) {
e.preventDefault()
console.log('CTRL F')
}
}, [])
useEffect(() => {
document.addEventListener('keydown', keyBindSearch)
return () => {
console.log('REMOVE')
document.removeEventListener('keydown', keyBindSearch)
}
}, [])
解决方案 2:
useEffect(() => {
const keyBindSearch = e => {
if ((e.metaKey && e.key === 'f') || (e.ctrlKey && e.key === 'f')) {
e.preventDefault()
console.log('CTRL F')
}
}
document.addEventListener('keydown', keyBindSearch)
return () => {
console.log('REMOVE')
document.removeEventListener('keydown', keyBindSearch)
}
}, [])
我在控制台中看到 REMOVE
,因此来自 useEffect
的清理函数肯定会触发,但事件侦听器并未删除,即使在调用清理函数后仍会记录 CTRL F
。< /p>
我做错了什么?
答案 0 :(得分:2)
至少解决方案 2 没有问题。请记住,当元素被移除并且不再渲染时,eventListener 将被移除(否则 useEffect 将再次绑定 eventListener)。请参阅我的示例,当您删除组件时,没有记录 CTRL F:https://codesandbox.io/s/epic-chatelet-e9qpv?file=/src/App.js
答案 1 :(得分:0)
尝试窗口而不是文档。 改变这个:
document.addEventListener('keydown', keyBindSearch) //change document to window
到:
window.addEventListener('keydown', keyBindSearch)
这样做也是为了删除。例如:
window.removeEventListener('keydown', keyBindSearch);
可能对你有用。干杯