React Custom Hooks Tutorial (2026)

How to Write Custom React Hooks

Custom hooks let you extract component logic into reusable functions. Here are 10 essential hooks every React developer needs.

useLocalStorage

function useLocalStorage<T>(key: string, initialValue: T) {
  const [storedValue, setStoredValue] = useState<T>(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch { return initialValue; }
  });
  const setValue = (value: T) => {
    setStoredValue(value);
    window.localStorage.setItem(key, JSON.stringify(value));
  };
  return [storedValue, setValue] as const;
}

useDebounce

1
2
3
4
5
6
7
8
function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState(value);
  useEffect(() => {
    const handler = setTimeout(() => setDebouncedValue(value), delay);
    return () => clearTimeout(handler);
  }, [value, delay]);
  return debouncedValue;
}

useFetch

1
2
3
4
5
6
7
8
9
function useFetch<T>(url: string) {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  useEffect(() => {
    fetch(url).then(r => r.json()).then(d => { setData(d); setLoading(false); }).catch(e => { setError(e.message); setLoading(false); });
  }, [url]);
  return { data, loading, error };
}

useWindowSize

1
2
3
4
5
6
7
8
9
function useWindowSize() {
  const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });
  useEffect(() => {
    const handler = () => setSize({ width: window.innerWidth, height: window.innerHeight });
    window.addEventListener('resize', handler);
    return () => window.removeEventListener('resize', handler);
  }, []);
  return size;
}

useClickOutside

1
2
3
4
5
6
7
8
9
function useClickOutside(ref: RefObject<HTMLElement>, callback: () => void) {
  useEffect(() => {
    const handler = (e: MouseEvent) => {
      if (ref.current && !ref.current.contains(e.target as Node)) callback();
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [ref, callback]);
}

useOnlineStatus

function useOnlineStatus() {
  const [online, setOnline] = useState(navigator.onLine);
  useEffect(() => {
    const on = () => setOnline(true);
    const off = () => setOnline(false);
    window.addEventListener('online', on);
    window.addEventListener('offline', off);
    return () => { window.removeEventListener('online', on); window.removeEventListener('offline', off); };
  }, []);
  return online;
}

Want All 10 Hooks Production-Ready?

Our React Hooks Library includes all 10 hooks with TypeScript types, tests, and interactive demos. 39 USD, one-time payment, unlimited projects.

Get it: rentry.co/devtools-store
Bundle (7 products): 249 USD
Pay: ETH/USDC/USDT to 0xA18dC9fA96089d273421a57C18de0bf1FE9FaB52
Email: [email protected]

Edit

Pub: 13 May 2026 17:27 UTC

Views: 5