React State Management Pattern
Choose the right state management approach for your React application scale
When to Use
- You are deciding how to manage state in a new React application
- Local component state is no longer sufficient (multiple components need the same data)
- Context re-render performance is becoming a problem
- You need derived state, selectors, or middleware (Redux DevTools, undo/redo)
Instructions
Decision tree:
- Local state first: Start with
useState / useReducer. Do not reach for global state until you have a specific problem.
- Shared low-frequency state: Use React Context +
useContext for data that rarely changes (theme, auth, locale).
- Shared high-frequency state (small apps): Use Zustand for minimal boilerplate, selector-based subscriptions, and devtools support.
- Complex domain state (large apps): Use Redux Toolkit for predictable state machines, time-travel debugging, and team consistency.
- Server state: Use React Query or SWR — not client state management — for data that comes from an API.
// Zustand: minimal setup
import { create } from 'zustand';
interface BearStore {
count: number;
increment: () => void;
}
const useBearStore = create<BearStore>((set) => ({
count: 0,
increment: () => set((s) => ({ count: s.count + 1 })),
}));
Details
State categories:
- UI state: Open/closed, selected tab, scroll position — local state or URL params
- Server state: API data — React Query, SWR, RTK Query
- Global app state: User session, theme, cart — Context or Zustand
- Complex domain state: Multi-entity updates, undo/redo, optimistic updates — Redux Toolkit
Library comparison (2024):
| Library |
Bundle |
Boilerplate |
DevTools |
Selectors |
| Context |
0KB |
Low |
No |
No |
| Zustand |
~1KB |
Very low |
Yes |
Yes |
| Jotai |
~3KB |
Low |
Yes |
Atoms |
| Redux Toolkit |
~12KB |
Medium |
Excellent |
Yes |
React 19 note: With the React compiler, many manual performance optimizations in Zustand/Redux become less necessary as React auto-memoizes.
Source
https://patterns.dev/react/state-management
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.
1---2name: react-state-management-pattern3description: React State Management Pattern4---5# React State Management Pattern67> Choose the right state management approach for your React application scale89## When to Use1011- You are deciding how to manage state in a new React application12- Local component state is no longer sufficient (multiple components need the same data)13- Context re-render performance is becoming a problem14- You need derived state, selectors, or middleware (Redux DevTools, undo/redo)1516## Instructions1718**Decision tree:**19201. **Local state first:** Start with `useState` / `useReducer`. Do not reach for global state until you have a specific problem.212. **Shared low-frequency state:** Use React Context + `useContext` for data that rarely changes (theme, auth, locale).223. **Shared high-frequency state (small apps):** Use Zustand for minimal boilerplate, selector-based subscriptions, and devtools support.234. **Complex domain state (large apps):** Use Redux Toolkit for predictable state machines, time-travel debugging, and team consistency.245. **Server state:** Use React Query or SWR — not client state management — for data that comes from an API.2526```typescript27// Zustand: minimal setup28import { create } from 'zustand';29interface BearStore {30 count: number;31 increment: () => void;32}33const useBearStore = create<BearStore>((set) => ({34 count: 0,35 increment: () => set((s) => ({ count: s.count + 1 })),36}));37```3839## Details4041**State categories:**4243- **UI state:** Open/closed, selected tab, scroll position — local state or URL params44- **Server state:** API data — React Query, SWR, RTK Query45- **Global app state:** User session, theme, cart — Context or Zustand46- **Complex domain state:** Multi-entity updates, undo/redo, optimistic updates — Redux Toolkit4748**Library comparison (2024):**49| Library | Bundle | Boilerplate | DevTools | Selectors |50|---------|--------|-------------|----------|-----------|51| Context | 0KB | Low | No | No |52| Zustand | ~1KB | Very low | Yes | Yes |53| Jotai | ~3KB | Low | Yes | Atoms |54| Redux Toolkit | ~12KB | Medium | Excellent | Yes |5556**React 19 note:** With the React compiler, many manual performance optimizations in Zustand/Redux become less necessary as React auto-memoizes.5758## Source5960https://patterns.dev/react/state-management6162## Process63641. Read the instructions and examples in this document.652. Apply the patterns to your implementation, adapting to your specific context.663. Verify your implementation against the details and edge cases listed above.6768## Harness Integration6970- **Type:** knowledge — this skill is a reference document, not a procedural workflow.71- **No tools or state** — consumed as context by other skills and agents.7273## Success Criteria7475- The patterns described in this document are applied correctly in the implementation.76- Edge cases and anti-patterns listed in this document are avoided.