All React templates

React Hooks Best Practices

Disciplined hook usage: deps arrays, custom hooks, refs, and effect minimalism.

DevZone Tools2,880 copiesUpdated Feb 14, 2026ReactTypeScript
# CLAUDE.md — React Hooks Best Practices

## Rules of Hooks

- Call hooks at the top level of a function component or another hook. Never inside loops, conditions, or after early returns.
- Hook names start with `use`. ESLint enforces this and it's load-bearing for the linter — don't rename around it.

## useState

- Initialize with the value, not a getter, unless construction is expensive: `useState(() => expensiveInit())`.
- One state per concern. Don't combine unrelated state into one big object.
- For derived state, compute during render. Don't sync via `useEffect`.

## useEffect — the last resort

- Effects are for synchronizing with external systems (DOM, network, timers). Not for "running code when X changes".
- If the body of an effect could be an event handler, it should be.
- Always specify the dep array. Empty `[]` only when you truly mean "once" and you're not using any value from the render.
- Always return a cleanup function for subscriptions, intervals, observers.
- Two effects, two responsibilities — never combine unrelated work into one effect.

## useRef

- For values that need to persist across renders without causing re-renders.
- For DOM refs: `useRef<HTMLInputElement>(null)`. Type the element narrowly.
- Mutating `ref.current` doesn't re-render. If you need a re-render, use state.

## useMemo / useCallback

- Default to *not* using them. They have a real cost — memoization itself takes work.
- Use them when:
  - A value is passed to a memoized child and identity matters
  - A computation is provably expensive (you've measured)
- Don't memoize primitive values. Don't memoize unstable inputs.

## Custom hooks

- A hook is a function that calls other hooks. Anything that doesn't is a utility — keep it as a plain function.
- One hook, one purpose. Compose smaller hooks; don't write a 200-line super-hook.
- Return tuples for two values where order is obvious (`[value, setValue]`). Return objects when you have 3+ named values.

## useReducer

- Reach for `useReducer` when state transitions are complex or multiple events update overlapping state.
- Reducers must be pure. No fetches, no side effects.
- Action types are string literals — type them as a discriminated union.

## Don't

- Don't use `useEffect` for data fetching when a server framework or query library is available.
- Don't read state values inside an effect via stale closures — add them to deps or use a ref.
- Don't create new objects/arrays in render and pass them to memoized children. Memoize them.
- Don't disable `react-hooks/exhaustive-deps`. Fix the dependency, don't hide the warning.

Other React templates