React State Management in 2024: What I Actually Use
Every React project I join seems to have a different state management setup. Redux, MobX, Zustand, Jotai, React Query, or just plain Context — the choices are overwhelming. After shipping React apps for companies like PwC, QBeat, and Interamerican, here is what I actually reach for.
For server state (data fetched from APIs), React Query (TanStack Query) is my default choice. It handles caching, background refetching, optimistic updates, and loading states out of the box. Before React Query, I was writing the same boilerplate fetch-loading-error logic in every project.
For client-only state that multiple components need, I start with React Context and useReducer. It is built into React, requires no extra dependencies, and is perfectly fine for most applications. I used this pattern extensively while building the admin panel at QBeat.
I reach for Zustand only when Context performance becomes an issue, typically in apps with very frequent state updates or deeply nested component trees. Zustand’s selector-based subscriptions prevent unnecessary re-renders without the boilerplate of Redux.
Redux still has its place in large teams where strict patterns and dev tools matter. At PwC, the existing Redux setup with Redux Toolkit worked well because the team was large and the predictable action-based flow helped with debugging complex payment transactions.
My rule of thumb: start simple with Context, add React Query for server state, and only introduce a dedicated state library when you feel real pain. Premature optimization of state management is one of the biggest time sinks in React development.