When useState Isn't Enough — Context, Zustand, Redux
State Management
Most app state is local. Some is shared. The "state management" question is really "where does this value live?"
What you'll learn
- Decide between local state, context, and a store
- Recognize when a library helps and when it doesn't
“State management” sounds heavy. The actual question is simple: where does this value live? The answer is usually one of four places.
The Four Tiers
| Tier | Use it when… |
|---|---|
Component state (useState) | One component cares |
| Lifted state (in a parent) | A few components share it |
| Context | Many components scattered across the tree need it |
| Store (Zustand/Redux) | Many components AND the state changes frequently |
Start at the top and only move down when you actually need to.
What Belongs Where
- Local state: form inputs, “is this open”, “what’s the active tab”
- Lifted state: a value shared between two siblings
- Context: theme, locale, current user, feature flags
- Store: shopping cart, complex form state across pages, real-time data
A Quick Zustand Example
Zustand is the lightest of the popular stores. The whole API:
import { create } from "zustand";
const useCart = create(set => ({
items: [],
add: item => set(state => ({ items: [...state.items, item] })),
clear: () => set({ items: [] }),
}));
function CartBadge() {
const count = useCart(state => state.items.length);
return <span>{count} items</span>;
}
function AddButton({ item }) {
const add = useCart(state => state.add);
return <button onClick={() => add(item)}>Add</button>;
} No provider. No reducer. Just a hook.
What About Redux?
Redux is still the most-used state library in larger codebases. Modern Redux uses Redux Toolkit — far simpler than what people remember. If your team already uses it, stay. For a new project, Zustand is usually easier.
”Server State” vs “Client State”
A useful split:
- Server state: things from the API — users, posts, search results. Use React Query or SWR.
- Client state: UI state, drafts, ephemeral UI —
useState, context, or a small store.
Mixing server state into Redux/Zustand is a common over-engineering mistake. Let React Query own server state; use a small store for the rest.
When You Don’t Need ANY of This
Most components only need useState. “We’re at 50 components and
still no global store” is a sign of good architecture, not missing
sophistication.
Up Next
How to style — the React ecosystem has options.
Styling Options →