Frontend State Management: When to Use What

Updated · techinterview.org

The state management landscape has consolidated significantly. The “Redux for everything” era is over; modern apps use specialized tools per state category. Senior frontend interviews probe whether you understand the categories and the right tool for each.

The five categories of state

  • Server state: data fetched from APIs (lists, items, user info)
  • Client state: UI state (selected tab, expanded item)
  • Form state: what the user is currently typing/selecting
  • URL state: route, query params, hash
  • Computed state: derived from other state

Different tools for different categories. Mixing them causes pain.

Server state: TanStack Query / SWR / Apollo

Built specifically for the lifecycle of data fetched from servers:

  • Caching with TTLs
  • Background refetching
  • Stale-while-revalidate
  • Mutations with optimistic updates
  • Pagination, infinite scroll
  • Retry logic

TanStack Query (formerly React Query) is the dominant choice in 2026. SWR is simpler. Apollo is for GraphQL specifically.

Client state: Zustand / Jotai / Redux Toolkit

For state that is yours, not the server’s:

Zustand

Tiny (~3KB), simple. Single store with hooks. The default for small-to-medium apps.

const useStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 }))
}));

Jotai

Atomic state. Each piece of state is an atom. Components subscribe to specific atoms; only re-render when those change.

Best for fine-grained state with many disjoint slices.

Redux Toolkit (RTK)

Modern Redux. Less boilerplate than classic Redux. Best for large apps with complex state interactions, time-travel debugging needs, or strict structural patterns.

Adoption is declining for new projects but RTK remains in many large codebases.

Form state: React Hook Form / Formik

Forms have unique requirements (validation, dirty tracking, submission). General state libraries do not handle them well.

React Hook Form is the modern default. Formik still in use; new projects pick RHF.

URL state: nuqs / route params

Search params (filters, page numbers, selected items) often belong in the URL — sharable, browser-back-friendly, indexable.

nuqs (or similar) provides typed query-param management without manual parsing/encoding.

The Redux trap

Older codebases store everything in Redux: server data, form state, UI state. This produces:

  • Boilerplate without benefit
  • Re-renders on every state change
  • Confused mental model — what kind of state is this?

Modern best practice: server state in TanStack Query, client state in Zustand or Context, form state in RHF, URL state in route library. Redux only where genuinely needed.

Context: when and when not

React’s built-in useContext is fine for:

  • Theme
  • Locale
  • Authentication state (current user)

Not great for:

  • Frequently updated state — every consumer re-renders on every change
  • Complex selectors
  • State that needs persistence

Selectors and memoization

For derived state from a store, use selectors:

const visibleTodos = useStore(s => s.todos.filter(t => !t.done));

Without memoization, the component re-renders on every store change, even unrelated ones. Most modern stores (Zustand, Redux Toolkit) handle selector memoization for you.

State that survives reload

Persistence options:

  • localStorage / sessionStorage — for non-sensitive client state
  • IndexedDB — for larger datasets
  • Server — for anything that should survive across devices

Zustand has a persist middleware. Redux has redux-persist. Both reasonably reliable for the common cases.

Common mistakes

  • Using Redux for server data instead of TanStack Query
  • useState + useEffect to fetch data (manual implementation of what libraries handle)
  • Putting too much in Context (re-render storm)
  • Storing form state at the global level (should be local)
  • Storing URL state somewhere other than the URL (loses shareability)

Frequently Asked Questions

What about Recoil?

Effectively dead. Replaced by Jotai for atomic state needs.

Should I use Server Components instead of state management?

For server-rendered content, yes — RSC reduces client-side state needs significantly. Interactive parts still need client state.

How do I structure a Zustand store for a large app?

Slice the store into independent stores by domain (user, cart, ui). Compose where needed. Keep each store small.

newsletter

What's actually being asked right now

Interview patterns & comp trends, straight to your inbox.

No spam. Unsubscribe anytime.

newsletter

What's actually being asked right now

Interview patterns & comp trends, straight to your inbox.

No spam. Unsubscribe anytime.

1972 Soviet postage stamp commemorating the Mars 2 probe

worth a read

Mars For The Rest of Us — a weekly-or-more deep dive on the technical side of Mars exploration: rocket propulsion, microbiology, mission architecture, and everything in between. Written by Maciej Ceglowski.

Read it on Substack
Scroll to Top