Reputation: 63
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
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
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