What are custom hooks?

In React, custom hooks let you extract and reuse stateful logic across multiple components. They are JavaScript functions that use built-in hooks like useState, useEffect, or useRef, and follow the naming convention useSomething.

Custom hooks don’t add new functionality to React, but they help you organize code more cleanly and reduce duplication.

Why use custom hooks?

BenefitExplanation
ReusabilityAvoid repeating logic across components
Clean componentsMove logic out of the component body
TestabilityLogic in hooks can be unit tested independently
Separation of concernsKeeps UI and logic separate

Basic structure of a custom hook

import { useState, useEffect } from 'react';

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

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return width;
}

Usage in a component:

function MyComponent() {
  const width = useWindowWidth();

  return <p>Window width: {width}px</p>;
}


Guidelines for writing custom hooks

  • Prefix with use to follow React’s rules of hooks
  • Use other hooks inside (e.g., useState, useEffect)
  • Keep them pure and focused on a single task
  • Return only what is needed (state, handlers, values)

More useful examples

1. Uselocalstorage

function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    const item = localStorage.getItem(key);
    return item ? JSON.parse(item) : initialValue;
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue];
}


2. Usefetch

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(setData)
      .finally(() => setLoading(false));
  }, [url]);

  return { data, loading };
}


When should you create a custom hook?

Create one when:

  • Multiple components share the same logic (e.g., form handling, API calls)
  • Logic inside a component gets too large
  • You want to abstract side effects (e.g., subscriptions, listeners)
  • You want better test coverage for business logic

Best practices

  • Follow React's Rules of Hooks
  • Don’t use hooks conditionally inside your custom hook
  • Keep return values intuitive and well-documented
  • Combine hooks when necessary (e.g., useState + useEffect)
  • Test hooks using tools like React Testing Library and @testing-library/react-hooks

Conclusion

Custom hooks are a powerful way to write cleaner, more modular React code. By abstracting logic into reusable functions, you can improve your app’s maintainability and reduce complexity in your components. Start simple, and extract logic as your components grow!