事件监听器没有被删除

时间:2020-05-25 14:21:51

标签: javascript jquery reactjs event-listener

此代码在加载DOM内容时注册滚动事件侦听器。卸载组件时,我正在调用removeEventListener()方法,但是事件侦听器未删除,而是在其他组件中调用。我要去哪里错了?谢谢!

useEffect(() => {
  return () => {
    document.removeEventListener('scroll', listener, true);
    console.log('unmount');
  };
}, []);

useLayoutEffect(() => {
  document.addEventListener('DOMContentLoaded', (event) => {
    document.addEventListener('scroll', listener, true);
  });
});

const listener = () => {
  let elementTop = $('.foo').offset().top;
  let elementBottom = elementTop + $('.foo').outerHeight();
  let viewportTop = $(window).scrollTop();
  let viewportBottom = viewportTop + $(window).height();
  let boolean = elementBottom > viewportTop && elementTop < viewportBottom;
  boolean ? setMapAbsolute(true) : setMapAbsolute(false);
};

2 个答案:

答案 0 :(得分:2)

由于添加事件处理程序不会更改屏幕上呈现的内容,因此建议您将其添加到您的useEffect()中,而不要添加到useLayoutEffect()中。您已经传递了一个空数组作为useEffect的依赖项列表,这将确保事件处理程序仅添加一次。

useEffect(() => {
  document.addEventListener('DOMContentLoaded', (event) => {
    document.addEventListener('scroll', listener, true);
  });
  return () => {
    document.removeEventListener('scroll', listener, true);
    console.log('unmount');
  };
}, []);

答案 1 :(得分:1)

您错过了依赖项中的空数组,因此,每次重新渲染时,侦听器都会重新连接。

useLayoutEffect(() => {
 document.addEventListener('DOMContentLoaded', (event) => {
 document.addEventListener('scroll', listener, true);
 });
},[]);
相关问题