Consider this snippet,
useEffect(() => {
document.addEventListener('mousedown', checkAndCloseMenu);
return () => document.removeEventListener('mousedown', checkAndCloseMenu);
}, []);
I am using this useEffect in an Higher Order Dropdown Component, I've seen very few professionals using these kinds of adding and remove Event Listeners. Is using these eventListeners anti-pattern ? If yes, what would be the correct approach.
CodePudding user response:
Adding and removing event listeners is not considered an anti-pattern.
useEffect(() => {
document.addEventListener('mousedown', checkAndCloseMenu);
return () => document.removeEventListener('mousedown', checkAndCloseMenu);
}, []);
Whenever/wherever possible it is preferred to use a React ref to access underlying DOMNodes:
const ref = React.useRef();
useEffect(() => {
const node = ref.current;
node.addEventListener('mousedown', checkAndCloseMenu);
return () => node.removeEventListener('mousedown', checkAndCloseMenu);
}, []);
...
<div ref={ref}> ..... </div>
or to attach the listeners directly
<div onm ouseDown={checkAndCloseMenu}> ..... </div>
but sometimes this is unavoidable when you need to listen to event from the window
and document
objects/nodes.
What is considered anti-pattern is directly mutating a global event listener.
document.onmousedown = checkAndCloseMenu;
Not only does doing so mutate a global object it will replace any existing values there. Don't do event handling like this.