Last updated: Apr 29, 2026

Hooks

React 16.8 introduced Hooks — functions that let you use state, effects, and other React features inside function components. Before hooks, adding state or lifecycle logic meant converting to a class component, dealing with this binding, constructor boilerplate, and wrapper hell from HoCs and render props. Hooks eliminated all of that.

Built-in Hooks

State

  • useState — local state in a function component
  • useReducer — complex state managed through a reducer function

Effects

  • useEffect — run side effects (data fetching, subscriptions, DOM mutations) after render
  • useLayoutEffect — same as useEffect but fires synchronously after DOM mutations, before the browser paints
  • useInsertionEffect — inject styles before layout reads; meant for CSS-in-JS libraries

Context

  • useContext — read a context value without a Consumer wrapper

Refs

  • useRef — hold a mutable value that persists across renders (commonly a DOM node)
  • useImperativeHandle — customize the ref value a parent sees when using ref

Performance

  • useMemo — memoize an expensive computation so it only recalculates when dependencies change
  • useCallback — memoize a function reference to avoid unnecessary re-renders of children
  • useTransition — mark a state update as non-urgent so the UI stays responsive (React 18)
  • useDeferredValue — defer re-rendering a value until higher-priority updates finish (React 18)

Identity

  • useId — generate a stable unique ID for accessibility attributes like htmlFor/id pairs (React 18)

Debug

  • useDebugValue — display a label for custom hooks in React DevTools

External Stores

  • useSyncExternalStore — subscribe to an external store with built-in tearing protection (React 18)

React 19

  • use — read a Promise or Context; unlike other hooks, it can be called conditionally
  • useActionState — track the return value and pending state of an async form action
  • useFormStatus — read the submission status of a parent <form> from a child component
  • useOptimistic — show an optimistic value instantly while an async operation settles

Custom Hooks

A custom hook is a function whose name starts with use and that composes built-in hooks. It lets you extract and share stateful logic between components without adding wrapper layers.

function useKeyPress(targetKey: string): boolean {
  const [pressed, setPressed] = useState(false);

  useEffect(() => {
    const down = (e: KeyboardEvent) => {
      if (e.key === targetKey) setPressed(true);
    };
    const up = (e: KeyboardEvent) => {
      if (e.key === targetKey) setPressed(false);
    };

    window.addEventListener("keydown", down);
    window.addEventListener("keyup", up);
    return () => {
      window.removeEventListener("keydown", down);
      window.removeEventListener("keyup", up);
    };
  }, [targetKey]);

  return pressed;
}

Any component can call useKeyPress("Enter") to react to that key — no HoC or render prop needed.

Rules of Hooks

  1. Call hooks at the top level only. No hooks inside loops, conditions, or nested functions. React relies on call order to match state to the right hook.
  2. Call hooks from React functions only. Either a function component or another custom hook — never a plain JavaScript function.

The eslint-plugin-react-hooks plugin enforces both rules at lint time.