Custom React hooks for reusable stateful logic.
A custom accessibility hook that announces dynamic updates through an aria-live region.
import { useAnnounce } from '@/client/hooks/use-announce';
const MyComponent = () => {
const announce = useAnnounce();
return <button onClick={() => { announce('Saved'); }}>Save</button>;
};| Approach | Complexity | Scope | Persistence | Best for |
|---|---|---|---|---|
useState |
Low | Single component | No | Form inputs, toggles, local UI state |
useReducer |
Medium | Single component | No | Complex state with multiple related transitions |
| Custom hook | Medium | Shared across components | Optional | Reusable logic (e.g. announcements, form validation) |
| Context + hook | Medium | Component subtree | Optional | Theme, locale, wizard state shared by a subtree |
| Redux | Higher | Global (whole app) | Yes (via middleware) | Auth state, persisted data, DevTools-visible state |
- Start with
useState. It covers the majority of cases. - Use
useReducerwhen a single component has multiple related state values and complex transitions (e.g. a form with validation, loading, and error states). - Extract a custom hook when multiple components need the same stateful logic. The hook encapsulates the reducer and side effects, keeping components clean.
- Add Context when a subtree of components needs shared state but it doesn't belong globally (e.g. a multi-step form wizard).
- Use Redux when state is truly global, needs to persist across sessions, benefits from DevTools, or is consumed by many unrelated components.
- Reaching for Redux first. Not every piece of state needs to be global. Start simple and escalate only when complexity demands it.
- Putting derived state in a reducer. If a value can be computed from other state, compute it during render instead of storing it.
- Skipping custom hooks. If you copy-paste the same state/effect pattern in multiple components, extract it into a hook.
- Over-using Context for frequent updates. Context re-renders every consumer on change. For rapidly changing state (e.g. mouse position, animation), prefer other approaches.