I have added an event listener to "keydown" event in my ReactJS application. Because of a third party library, I'm adding it via setTimeout in a useEffect, this component is like a popup, so it mounts-unmounts lots of times in the app lifecycle. Its like below;
useEffect(() => {
const timeoutID = setTimeout(() => {
clearTimeout(timeoutID);
window.addEventListener("keydown", theFunction, true);
}, 500);
function theFunction(event: KeyboardEvent) {
// do something
}
return () => {
window.removeEventListener("keydown", theFunction, true);
};
}, []);
It's a typical usage, to remove event listener using removeEventListener method. The problem is, when the component unMounts, the event stays and stacks up on top of another. I'm actually seeing it on the Event Listeners tab on Devtools.
I was suspecting that, every time this component mounts, theFunction changes in the memory, so it's not the same function and therefore React can't remove it. I took theFunction from the useEffect and put it to the top of the component (outside of the functional component definition, just below the imports).
// imports
function theFunction(event: KeyboardEvent) {
// do something
}
const Component = () => {
useEffect(() => {
const timeoutID = setTimeout(() => {
clearTimeout(timeoutID);
window.addEventListener("keydown", theFunction, true);
}, 500);
return () => {
window.removeEventListener("keydown", theFunction, true);
};
}, []);
And voila! The event is now adding just once and does not stack.
I'm not sure is it really beacuse theFunction was not same each time (as I thought) the component unMounts, or is there another React thing that I'm missing. Why React does not removes this eventListener on unMount in this case?
Edit: React version: 16, strict mode is on