dm98
dm98

Reputation: 63

Event listener is not getting removed

This code is registering a scroll event listener when DOM content is loaded. When the component is unmounted I am calling the removeEventListener() method, but the event listener is not removed and is being invoked in other components. Where am I going wrong? Thanks!

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);
};

Upvotes: 2

Views: 565

Answers (2)

Siddharth Patel
Siddharth Patel

Reputation: 61

you have missed an empty array in dependencies, hence the listener is getting reattached on every rerender.

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

Upvotes: 1

Ed Lucas
Ed Lucas

Reputation: 7355

Since adding an event handler does not change what renders on the screen, I would recommend adding it in your useEffect() instead of in useLayoutEffect(). You are already passing an empty array as a list of dependencies to useEffect, which will ensure that the event handler is only added once.

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

Upvotes: 2

Related Questions