# Frontend State Management: When to Use What

Source: https://www.techinterview.org/post/3233475108/frontend-state-management-zustand-jotai-redux/
Updated: 2026-06-30 · 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.
