A global custom hook events listener
This is a really simple and straightforward, but also, a really useful custom hook.
This custom React hook takes care of setting up an event listener on a component, mount it, and removing the listener on component unmount.
Let's take a look at the addEventListener and removeEventListener function definitions so we can see what parameters we need to pass to the custom hook in order to make it flexible for all use-cases.
target.addEventListener(type, listener[, options]);
target.removeEventListener(type, listener[, options]);
From the definitions, we can see that both functions use the following parameters: target, type, listener and options. Now that we've established the input parameters, we can go ahead and create our hook.
For a complete reference, please take a look on MDN
const useEventListener = (eventName, handler, element = window) => {
const savedHandler = useRef();
useEffect(() => {
savedHandler.current = handler;
}, [handler]);
useEffect(
() => {
const isSupported = element && element.addEventListener;
if (!isSupported) return;
const eventListener = (event) => savedHandler.current(event);
element.addEventListener(eventName, eventListener);
return () => {
element.removeEventListener(eventName, eventListener);
};
},
[eventName, element] // Re-run if eventName or element changes
);
}
export { useEventListener }
And then a simple usage
import { useState, useCallback } from 'react';
// Usage
function App() {
const [coords, setCoords] = useState({ x: 0, y: 0 });
const handler = useCallback(
({ clientX, clientY }) => {
setCoords({ x: clientX, y: clientY });
},
[setCoords]
);
// Add event listener using our hook
useEventListener('mousemove', handler);
return (
<h1>
The mouse position is ({coords.x}, {coords.y})
</h1>
);
}