Easy to understand React Hook recipes by Gabe Ragland
What's all this about?

Hooks are a new addition in React that lets you use state and other React features without writing a class. This website provides easy to understand code examples to help you learn how hooks work and inspire you to take advantage of them in your next project. You may also like my React app builder ✨️

📩  Get new recipes in your inbox
Join 5,145 subscribers. No spam ever.


If you find yourself adding a lot of event listeners using useEffect you might consider moving that logic to a custom hook. In the recipe below we create a useEventListener hook that handles checking if addEventListener is supported, adding the event listener, and removal on cleanup. See it in action in the CodeSandbox demo.

import { useState, useRef, useEffect, useCallback } from 'react';

// Usage
function App(){
  // State for storing mouse coordinates
  const [coords, setCoords] = useState({ x: 0, y: 0 });
  // Event handler utilizing useCallback ...
  // ... so that reference never changes.
  const handler = useCallback(
    ({ clientX, clientY }) => {
      // Update coordinates
      setCoords({ x: clientX, y: clientY });
  // Add event listener using our hook
  useEventListener('mousemove', handler);
  return (
      The mouse position is ({coords.x}, {coords.y})

// Hook
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 us needing to pass it in effect deps array ...
  // ... and potentially cause effect to re-run every render.
  useEffect(() => {
    savedHandler.current = handler;
  }, [handler]);

    () => {
      // Make sure element supports addEventListener
      // On 
      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
  • donavon/use-event-listener - Original source for this hook available as a library
  • Divjoy - The easiest way to start your next React project. Pick everything you need, like auth, analytics, payments, and more + a nice looking template and then export a complete React codebase. It saves you weeks of development time.
Next recipe: