useEventListenerLoading saved progress…

useEventListener

Build a hook that subscribes to a DOM event and unsubscribes automatically. Wiring up addEventListener by hand inside a component is repetitive and error-prone: you have to attach the listener, remember to remove it on unmount, and keep the handler from going stale across renders. useEventListener(eventName, handler, element) packages all of that — it attaches handler for eventName on the target (defaulting to window), always calls the latest handler, and removes the listener when the component unmounts or the target changes.

Signature

function useEventListener(
  eventName: string,
  handler: (event: Event) => void,
  element?: EventTarget, // defaults to window
): void;

The hook returns nothing. It is the foundation other DOM hooks build on — useHover, useClickOutside, useKeyPress, and useWindowSize are all thin layers over this pattern.

Examples

function WindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);

  // Re-read the width whenever the window resizes. Cleanup is automatic.
  useEventListener('resize', () => setWidth(window.innerWidth));

  return <span>{width}px</span>;
}
// Attach to a specific element instead of window:
const ref = useRef(null);
useEventListener('click', handleClick, ref.current);

Notes

  • Defaults to window. Omitting element subscribes on window; passing one subscribes on that target instead.
  • The handler must never go stale. If the component re-renders with a new handler (inline handlers are recreated every render), the next event must call the new one — without re-subscribing.
  • Clean up on unmount. The listener must be removed when the component unmounts, or it leaks and fires into a component that no longer exists.
  • Re-subscribe only when it matters. Changing the eventName or element should move the subscription; merely changing the handler should not.
Loading editor…