Every built-in React hook in one place, including the React 19 additions. Each entry has the signature, a working example, and practical tips. Bookmark this and stop Googling.
| Name | Syntax | Description |
|---|---|---|
| useState | const [state, setState] = useState(initial) | Reactive state variable. Triggers re-render on change. |
| useEffect | useEffect(() => { ... return cleanup }, [deps]) | Side effects after render. Cleanup runs before next effect and on unmount. |
| useRef | const ref = useRef(initialValue) | Mutable value that persists across renders without triggering re-renders. |
| useMemo | const value = useMemo(() => compute(a, b), [a, b]) | Caches a computed value. Only recalculates when dependencies change. |
| useCallback | const fn = useCallback(() => { ... }, [deps]) | Caches a function reference. Useful for stable props to memoized children. |
| useReducer | const [state, dispatch] = useReducer(reducer, init) | State machine pattern. Better than useState for complex state logic. |
| useContext | const value = useContext(MyContext) | Reads the nearest context provider's value. |
| useTransition | const [isPending, startTransition] = useTransition() | Marks state updates as non-blocking. Keeps the UI responsive. |
| useId | const id = useId() | Generates a stable unique ID safe for SSR hydration. |
| use (React 19) | const data = use(promise) | Reads a Promise or Context during render. Can be called conditionally. |
useState<T>(initialValue: T | (() => T))Returns a state variable and its setter. The setter accepts either a new value or a function that receives the previous state.
Tips
useReducer(reducer, initialState, init?)State management via action dispatch. Prefer over useState when state has multiple sub-values, next state depends on previous, or state transitions follow clear rules.
Tips
useEffect(setup, dependencies?)Synchronizes your component with an external system (APIs, subscriptions, DOM manipulation). The cleanup function runs before the next effect and on unmount.
Tips
useLayoutEffect(setup, dependencies?)Same API as useEffect, but fires synchronously after DOM mutations and before the browser paints. Use for DOM measurements or mutations that must be visible immediately.
Tips
useRef<T>(initialValue: T)Returns a mutable ref object whose .current property persists across renders. Changing it does not trigger a re-render. Two main uses: DOM element access and storing mutable values.
Tips
useImperativeHandle(ref, createHandle, dependencies?)Customizes the instance value exposed to parent components via ref. Use sparingly — prefer passing data through props.
Tips
useMemo(() => computeValue(a, b), [a, b])Memoizes a computed value. Only recalculates when dependencies change. Not a guarantee — React may drop the cache under memory pressure.
Tips
useCallback(fn, dependencies)Caches a function so its reference stays the same between renders. useCallback(fn, deps) is equivalent to useMemo(() => fn, deps).
Tips
const [isPending, startTransition] = useTransition()Marks a state update as non-blocking. React will interrupt the transition to handle urgent updates (like typing), keeping the UI responsive.
Tips
const value = use(resource)Reads a Promise or Context during render. Unlike other hooks, use() can be called inside conditionals and loops. When reading a Promise, it integrates with Suspense for loading states.
Tips
const [state, formAction, isPending] = useActionState(action, initialState)Manages form state based on the result of a form action. Works with both client and server actions. The form works even before JavaScript loads (progressive enhancement).
Tips
const [optimistic, addOptimistic] = useOptimistic(state, updateFn)Shows an optimistic state while an async action is in progress. Automatically reverts if the action fails. Makes the UI feel instant.
Tips
Syncs state to localStorage. The lazy initializer reads the stored value on mount, and the effect persists it on change. This is the most common custom hook pattern.
Separate state and dispatch into two contexts so components that only dispatch don't re-render when state changes. Lightweight alternative to Redux or Zustand for medium complexity state.
useEffect fires after paint, not before — if you see a flicker, you need useLayoutEffect
Switch to useLayoutEffect for DOM measurements or mutations that must be visible immediately (tooltip positioning, scroll restoration). But don't overuse it — it blocks painting.
Stale closures: an effect or callback captures an old variable value because the dependency array is wrong
Always include every value from the component scope that the effect reads. Use the eslint-plugin-react-hooks exhaustive-deps rule — it catches this automatically.
Infinite re-render loop: setting state inside useEffect without proper dependencies
Never set state unconditionally inside an effect. Make sure the dependency array doesn't include values that the effect itself changes, or use a ref to break the cycle.
useMemo/useCallback don't prevent re-renders by themselves — the child must be wrapped in React.memo
Memoizing a prop value is useless if the child component re-renders regardless. Only reach for useMemo/useCallback when the child is wrapped in React.memo or the value is an effect dependency.
useRef changes don't trigger re-renders — if you need reactivity, use state
useRef is for values you want to persist without causing renders (DOM refs, interval IDs, previous values). If the UI should update when the value changes, use useState.
Go beyond the cheatsheet with hands-on lessons and challenges.