Core Hooks and the Rules of Hooks

This section documents React 19.x for the web, using function components and Hooks throughout (class components appear only where React still requires them, such as error boundaries). React Native is out of scope and gets only a pointer. The React 19 additions follow the current official React documentation. This content was generated with the assistance of AI and should be verified against react.dev before being relied on in production, since React APIs continue to evolve between releases.

This section’s bibliography lists the reference material consulted while preparing these pages.

Hooks are functions whose name starts with use that let a function component "hook into" React features — state, context, refs, effects, and more. This page covers the rules that govern all Hooks and the core state Hooks; the others have their own pages.

The Rules of Hooks

  1. Only call Hooks at the top level. Not inside conditions, loops, nested functions, or after an early return. React identifies each Hook by its call order, which must be identical on every render.

  2. Only call Hooks from React functions. From a component body or from another custom Hook — never from a plain function or an event handler.

function Profile({ id }) {
  const [user, setUser] = useState(null);   // OK: top level

  if (!id) return null;                      // early return AFTER all Hooks

  // const [x] = useState(0);                // BUG: Hook after a conditional return
}

The eslint-plugin-react-hooks plugin (in the default Vite React template) flags violations and checks Effect dependency arrays. See Rules of Hooks.

useState vs. useReducer

Reach for useReducer when state updates are complex, involve several sub-values, or the "next state" logic is worth testing in isolation. A reducer is a pure function (state, action) ⇒ nextState.

import { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment': return { count: state.count + 1 };
    case 'set':       return { count: action.value };
    default:          throw new Error('unknown action: ' + action.type);
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });
  return (
    <button onClick={() => dispatch({ type: 'increment' })}>{state.count}</button>
  );
}

useRef and useId

useRef holds a mutable value in .current that persists across renders and does not trigger one when it changes — a timer id, a previous value, or a DOM node (full DOM treatment on Refs and the DOM).

function Timer() {
  const timerRef = useRef(null);          // { current: null }, survives re-renders

  function start() {
    timerRef.current = setInterval(tick, 1000);   // writing .current does NOT re-render
  }
  function stop() {
    clearInterval(timerRef.current);
  }
  // ...
}

Read or write ref.current only in event handlers or Effects, never during render — doing it in the component body makes render impure (see The Rules of React).

useId generates a stable, unique string id for accessibility attributes, consistent between server and client — never use it for list keys.

function Field() {
  const id = useId();
  return (
    <>
      <label htmlFor={id}>Email</label>
      <input id={id} type="email" />
    </>
  );
}

useDebugValue labels a custom Hook in React DevTools. References: useRef, useId.

Every built-in Hook

Each links to its reference page at https://react.dev/reference/react/<name>; (or react-dom where noted).

Table 1. State
Hook Purpose

useState

A state variable and its setter. See State and Events.

useReducer

State driven by a reducer function (above).

Table 2. Context
Hook Purpose

useContext

Read a context value. See State Management.

Table 3. Refs
Hook Purpose

useRef

A mutable value that does not cause re-renders.

useImperativeHandle

Customize the ref handle a component exposes (rare). See Refs and the DOM.

Table 4. Effects
Hook Purpose

useEffect

Synchronize with an external system. See Effects.

useEffectEvent

Extract non-reactive logic from an Effect; reads the latest props/state without being a dependency (stable since React 19.2). See Effects.

useLayoutEffect

Like useEffect, but fires before the browser paints.

useInsertionEffect

For CSS-in-JS libraries to inject styles.

Table 5. Performance
Hook Purpose

useMemo

Cache an expensive calculation between renders. See Performance.

useCallback

Cache a function definition between renders.

useTransition

Mark a state update as a non-blocking transition.

useDeferredValue

Defer re-rendering a non-urgent part of the UI.

Table 6. Other
Hook Purpose

useDebugValue

Label a custom Hook in React DevTools.

useId

A unique id for accessibility attributes.

useSyncExternalStore

Subscribe to an external store. See Custom Hooks.

useActionState

Form/action state, pending and errors. See Forms and Actions.

useOptimistic

Show an optimistic state while an action is pending.

use

Read a promise or context during render. See Code Splitting and Suspense.

useFormStatus (react-dom)

Pending state of the enclosing <form>.

See the full index at Built-in React Hooks.