Part III β The Speed Β· Lesson 6.1
State Management
In one lineSort state by who owns it β server, URL, or client β and most of the hard problem disappears.
Where you've seen itCopying a filtered search URL into Slack and having a colleague open the identical view.
Diagram
FOUR KINDS OF STATE β different owners, different tools
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SERVER STATE users, orders, feed β
β owner: the backend. You hold a CACHE of it (6.9). β
β tool: React Query / RTK Query / SWR / Apollo β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β URL STATE filters, page, sort, open tab, search term β
β owner: the address bar. Shareable, back-button-able. β
β tool: the router β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β CLIENT STATE theme, sidebar open, wizard step, cart β
β owner: your app. Genuinely global, genuinely local. β
β tool: useState / Context / Zustand / Redux β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β FORM STATE field values, touched, errors β
β owner: the form. High-frequency, short-lived. β
β tool: react-hook-form / Formik β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Most "state management is hard" complaints are server state
being stored as if it were client state.THE SCOPE LADDER β climb only when forced
useState one component β start here
β needed by a child several levels down
βΌ
props / composition pass it down β often enough
β needed by many, changes rarely
βΌ
Context theme, auth, locale β re-renders all
β consumers
β needed by many, changes often
βΌ
external store Zustand / Redux β selective
subscriptions
Skipping to the bottom rung on day one is the classic over-engineering.WHY CONTEXT IS NOT A STORE
<Provider value={{user, cart, theme}}>
β any field changes βββΊ EVERY consumer re-renders
β
Zustand/Redux: useStore(s => s.cart.count)
β only components selecting cart.count re-renderHow it works
- Classify first. Ask "who is the source of truth?" Server state gets a caching library, not a global store.
- Push filters and pagination into the URL β you get shareability, deep links, and back-button behaviour for free.
- Keep client state as local as possible, lifting only when a second consumer genuinely appears.
- Use Context for low-frequency, wide-reach values (theme, auth, locale); use a store with selectors for anything that changes often.
- Derive, don't duplicate. Totals, filtered lists, and counts should be computed from state, never stored alongside it.
Trade-offs
| Tool | Fits | Cost |
|---|---|---|
useState | Local UI | Prop drilling if over-lifted |
| Context | Theme, auth, locale | Re-renders all consumers |
| Zustand | Global client state, small API | Another concept in the codebase |
| Redux Toolkit | Large apps, devtools, middleware | Boilerplate, learning curve |
| React Query | All server state | Not for client-only state |
Interview angle
"Which state management library would you choose?"
- Reframe first: most of the state is server state, so the real answer is a caching library plus the URL.
- What's left is genuinely small β theme, modals, cart β and
useStateplus one lightweight store usually covers it. - Choose Redux when you need time-travel debugging, middleware, or a large team needing strict conventions β not by default.
Recap
- Server, URL, client, form β classify before choosing a tool.
- Filters and pagination belong in the URL, not in a store.
- Context broadcasts; stores let components subscribe selectively.