Custom Hooks
โš›๏ธ React 18+ ๐ŸŸข Chapter 29 of 39 ๐Ÿ“‚ Phase 12: Reusable Architecture ๐Ÿ“… 2026 Edition
๐Ÿ“Œ Covered in this chapter: Custom Hook Definition ยท Naming Rules ยท useFetch ยท useLocalStorage ยท useDebounce ยท useOnlineStatus ยท Sharing Stateful Logic
A custom Hook is a regular JavaScript function, prefixed with "use", that lets you extract and reuse stateful logic between components โ€” the final, capstone concept in this course, built directly on top of useState and useEffect.
1Why Custom Hooks Exist

Imagine three different components that each need to track window width, fetch similar data, or subscribe to online status โ€” copy-pasting the same useState + useEffect logic into each one is repetitive and hard to keep in sync when it needs a fix. A custom Hook extracts that logic into one reusable function.

2Building useOnlineStatus
๐Ÿ’ป Example 1: Extracting the Network Status Logic from Chapter 19
import { useEffect, useState } from "react";

function useOnlineStatus() {
  const [isOnline, setIsOnline] = useState(navigator.onLine);

  useEffect(() => {
    const goOnline = () => setIsOnline(true);
    const goOffline = () => setIsOnline(false);

    window.addEventListener("online", goOnline);
    window.addEventListener("offline", goOffline);

    return () => {
      window.removeEventListener("online", goOnline);
      window.removeEventListener("offline", goOffline);
    };
  }, []);

  return isOnline;
}

// Now ANY component can use it in one line:
function StatusBadge() {
  const isOnline = useOnlineStatus();
  return <span>{isOnline ? "๐ŸŸข" : "๐Ÿ”ด"}</span>;
}
๐Ÿ” Important:

Custom Hooks share logic, not state itself โ€” each component calling useOnlineStatus() gets its own completely independent isOnline state, they just all run the identical underlying logic.

3Two More Practical Custom Hooks
// useLocalStorage - state that automatically persists across page reloads
function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    const stored = localStorage.getItem(key);
    return stored ? JSON.parse(stored) : initialValue;
  });

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

  return [value, setValue];
}

// useDebounce - delays updating a value until typing pauses
function useDebounce(value, delay) {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);

  return debounced;
}

useDebounce directly solves the search-on-every-keystroke problem flagged back in Chapter 22 โ€” pair it with a search input, and API calls only fire once the user pauses typing.

โš ๏ธ Forgetting the 'use' Naming Prefix

React's Hook rules (like being able to call useState inside them, and the rules-of-hooks ESLint checks) only apply to functions named starting with use. Naming your function getOnlineStatus instead of useOnlineStatus means React's tooling won't recognize it as a Hook, and calling other Hooks inside it may not work correctly.

๐Ÿ’ป Hands-on Interactive Practice Challenge

Build a custom useToggle hook that manages a boolean value with a function to flip it, then use it to control a simple show/hide panel.

React Practice Challenge โ–ถ Run in Compiler
import { useState } from "react";

function useToggle(initialValue = false) {
  const [value, setValue] = useState(initialValue);
  const toggle = () => setValue(v => !v);
  return [value, toggle];
}

function Panel() {
  const [isVisible, toggleVisible] = useToggle(false);

  return (
    <>
      <button onClick={toggleVisible}>Toggle Panel</button>
      {isVisible && <p>Panel content!</p>}
    </>
  );
}
Run This Challenge in Online JS IDE โ†’
โ“ Frequently Asked Questions (FAQ)

Q Can a custom Hook call other Hooks inside it?

Yes โ€” that's exactly the point. A custom Hook is just a regular function that's allowed to call useState, useEffect, useRef, or even other custom Hooks internally, composing them into one reusable piece of logic.

Q Where should custom Hooks live in a project's folder structure?

A common convention is a dedicated hooks/ folder inside src/ (e.g., src/hooks/useOnlineStatus.js), separate from the components/ folder, making them easy to find and reuse across the whole app.

OC
Written by Our Compiler Technical Editorial Team
Reviewed for accuracy & tested on React 18+ ยท Last updated August 2026