JAVASCRIPT

How to safely attach and detach event listeners with useEventListener

Discover `useEventListener`, a custom React hook for declaratively attaching global or element-specific event listeners with proper cleanup, preventing memory leaks.

import { useRef, useEffect } from 'react';

function 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]);
}

// Example Usage:
// function MyComponent() {
//   const [coords, setCoords] = useState({ x: 0, y: 0 });
//   const handleMouseMove = (event) => {
//     setCoords({ x: event.clientX, y: event.clientY });
//   };

//   useEventListener('mousemove', handleMouseMove);

//   return (
//     <div>
//       <h1>Mouse Position:</h1>
//       <p>X: {coords.x}, Y: {coords.y}</p>
//     </div>
//   );
// }

// // Example with a specific element:
// function ButtonComponent() {
//   const buttonRef = useRef(null);
//   const [clicks, setClicks] = useState(0);

//   const handleClick = () => {
//     setClicks(c => c + 1);
//   };

//   useEventListener('click', handleClick, buttonRef.current);

//   return (
//     <button ref={buttonRef}>Clicked {clicks} times</button>
//   );
// }
How it works: The `useEventListener` hook simplifies the process of attaching and detaching event listeners to the `window` object or a specified DOM element. It ensures that the event listener is correctly added when the component mounts and removed when it unmounts, preventing memory leaks. By storing the handler in a `useRef`, it avoids issues with stale closures and ensures the latest handler is always called, even if its dependencies change.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs