反应 useEffect 不清理事件侦听器

时间:2021-02-11 07:29:11

标签: reactjs react-hooks addeventlistener event-listener use-effect

我尝试了以下 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>

我做错了什么?

2 个答案:

答案 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);

可能对你有用。干杯