JAVASCRIPT
Attach and Clean Up Event Listeners with useEventListener
A versatile React hook to simplify adding and removing event listeners on DOM elements or the global window/document, ensuring proper cleanup.
import { useRef, useEffect } from 'react';
function useEventListener(eventName, handler, element = window) {
// Create a ref that stores handler
const savedHandler = useRef();
// Update ref.current value if handler changes. This allows our effect below to always get latest handler without needing to be re-run.
useEffect(() => {
savedHandler.current = handler;
}, [handler]);
useEffect(() => {
// Make sure element supports addEventListener
const isSupported = element && element.addEventListener;
if (!isSupported) return;
// Create event listener that calls handler function stored in ref
const eventListener = (event) => savedHandler.current(event);
// Add event listener
element.addEventListener(eventName, eventListener);
// Remove event listener on cleanup
return () => {
element.removeEventListener(eventName, eventListener);
};
}, [eventName, element]); // Re-run if eventName or element changes
}
export default useEventListener;
How it works: The `useEventListener` hook simplifies the process of attaching and detaching event listeners to the DOM. It accepts an `eventName`, a `handler` function, and an optional `element` (defaults to `window`). It automatically adds the listener on mount and removes it on unmount, preventing memory leaks. By storing the handler in a `ref`, it ensures the event listener always uses the latest handler function without needing to re-attach on every render.