Choosing a state management approach as the app grows
Most React projects start with local state and context and that is correct for the first several months. Problems show up when server data, form state and UI state all get managed the same way, because context re-renders everything under it and a growing app starts feeling sluggish for reasons that are hard to trace.
We split state by kind rather than by feature. Server data (anything that came from an API) goes through TanStack Query so caching, retries and background refetching are handled once instead of reinvented per screen. Client-only state that several components need, like a selected filter set or a modal stack, goes into a small Zustand store. Form state stays local to the form. This split is more work to set up than one global store, and it is the difference between an app that stays fast at 200 components and one that needs a rewrite at 50.
- Server state through TanStack Query, not stored in Redux or context
- Cross-cutting client state in a small dedicated store, scoped to what actually needs it
- Form state kept local and validated with the same schema used on the server











