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
-
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. -
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>
);
}
References: useState,
useReducer,
Extracting State Logic into a Reducer.
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" />
</>
);
}
Every built-in Hook
Each links to its reference page at https://react.dev/reference/react/<name> (or react-dom where noted).
| Hook | Purpose |
|---|---|
A state variable and its setter. See State and Events. |
|
State driven by a reducer function (above). |
| Hook | Purpose |
|---|---|
Read a context value. See State Management. |
| Hook | Purpose |
|---|---|
A mutable value that does not cause re-renders. |
|
Customize the ref handle a component exposes (rare). See Refs and the DOM. |
| Hook | Purpose |
|---|---|
Synchronize with an external system. See Effects. |
|
Extract non-reactive logic from an Effect; reads the latest props/state without being a dependency (stable since React 19.2). See Effects. |
|
Like |
|
For CSS-in-JS libraries to inject styles. |
| Hook | Purpose |
|---|---|
Cache an expensive calculation between renders. See Performance. |
|
Cache a function definition between renders. |
|
Mark a state update as a non-blocking transition. |
|
Defer re-rendering a non-urgent part of the UI. |
| Hook | Purpose |
|---|---|
Label a custom Hook in React DevTools. |
|
A unique id for accessibility attributes. |
|
Subscribe to an external store. See Custom Hooks. |
|
Form/action state, pending and errors. See Forms and Actions. |
|
Show an optimistic state while an action is pending. |
|
Read a promise or context during render. See Code Splitting and Suspense. |
|
|
Pending state of the enclosing |
See the full index at Built-in React Hooks.