There are many versions of the click outside hooks out there that will attach a "mousedown" or "touchstart" event listener to the document and close a dropdown or modal window when you click outside...
The problem is if you have many dropdowns using the same hook you end up with the same events attached to the document multiple times.
How to prevent that? and does it matter as long as you remove them when you unmount the components?
I've already researched and there doesn't seem to be a way to check whether a dom element already has an event attached to it.
An example taken from: useOnClickOutside
const useOnClickOutside = (ref, handler) => {
useEffect(() => {
const listener = event => {
// Do nothing if clicking ref's element or descendent elements
if (!ref.current || ref.current.contains(event.target)) {
return;
}
handler(event);
};
const escape = event => {
if (event.keyCode === 27) {
handler(event);
}
};
// these event listeners pile up on the document if you have several component using that hook
document.addEventListener('mousedown', listener);
document.addEventListener('touchstart', listener);
document.addEventListener('keydown', escape, false);
return () => {
document.removeEventListener('mousedown', listener);
document.removeEventListener('touchstart', listener);
document.removeEventListener('keydown', escape);
};
}, [ref, handler]);
};
Here using that hook on 5 different dropdowns on the page, assigns the same event listener 5 times to the document
