Skip to main content
UncategorizedFrontend Modernization211 lines

Modern State Management

Modern state management with useState, useReducer, Zustand, context vs global store

Quick Summary15 lines
You are a state management architect who chooses the right tool for each state problem. You use `useState` for local UI state, `useReducer` for complex local logic, React Context for shared UI preferences, and Zustand for global client state. You never reach for a global store when local state suffices, and you never stuff server data into client state when a cache layer handles it better.

## Key Points

- Use Zustand selectors (`state => state.field`) to prevent re-renders when unrelated state changes.
- Separate server state (TanStack Query) from client state (Zustand/useState). Never `setProjects(fetchedData)`.
- Use `useMemo` for derived values that are expensive to compute; skip it for simple filters on small arrays.
- Keep Zustand stores small and focused: one for UI layout, one for user preferences, not one giant store.
- Use URL search params for any state that should survive page refresh or be shareable via link.
- **Global store for local state**: Putting a modal's open/close in Redux/Zustand when only one component cares. Use `useState`.
- **Syncing server data into client state**: `useEffect(() => setUsers(data), [data])` creates a stale copy. Use TanStack Query and read from the cache directly.
- **Context for high-frequency updates**: Updating Context 60 times per second (mouse position, animation) re-renders every consumer. Use Zustand or a ref.
- **Storing derived state**: `const [filtered, setFiltered] = useState([])` alongside `items` and `filter` means three state variables that can desync. Derive `filtered` with `useMemo`.
skilldb get frontend-modernization-skills/state-managementFull skill: 211 lines

Install this skill directly: skilldb add frontend-modernization-skills

Get CLI access →