← All topics

State Management Interview Questions and Answers

useState and useReducer, prop drilling, Context, Redux Toolkit, Zustand, and server state with TanStack Query, RTK Query, SWR and React Router loaders/actions.

225 questions for State Management interviews with answers and explanations - Junior, Middle and Senior levels. Sample questions, online quizzes and coding tasks.

Questions by level

Sample questions

A few questions from each level with the correct answer and an explanation.

State Management · Junior

  1. What is "state" in a React component?

    Correct answer: Data that changes over time and affects what's on screen; a change triggers a re-render

    State is the component's memory between renders: a counter value, form input, whether a menu is open. A regular let variable resets on every render and its change doesn't tell React to update the UI. Props are read-only inputs owned by the parent.

  2. When should you use the functional update setCount(c => c + 1) instead of setCount(count + 1)?

    Correct answer: When the new value depends on the previous one, especially with several updates in a row

    count is a snapshot of the current render. Three setCount(count + 1) calls in one handler produce +1, while three setCount(c => c + 1) produce +3, because each updater receives the result of the previous one. It also protects against stale closures in timers and effects.

  3. How do you remove an item with id from an array in state?

    Correct answer: setItems(items.filter(i => i.id !== id))

    State must be updated immutably: filter, map, spread and toSorted create a new array. splice and delete mutate the existing one, the reference stays the same, and React skips the update.

  4. Why pass a function to useState(() => createInitialTodos())?

    Correct answer: So the expensive computation runs only on the first render

    useState(createInitialTodos()) calls the function on every render, even though the result is used only once. A lazy initializer useState(createInitialTodos) is called only on mount. It must be synchronous and pure.

All 75 questions with answers →

State Management · Middle

  1. How do you reset a form component's state when the selected user changes?

    Correct answer: Render it with key={userId} so React recreates the component

    A different key makes React treat it as a new component: old state is dropped and the initial values apply. A resetting effect first renders stale data and then fixes it - an extra render and a visible flash.

  2. How do you pass dispatch from useReducer deep into the tree without prop drilling?

    Correct answer: Put dispatch into its own context; it never changes, so consumers don't re-render

    The "reducer + context" pattern: one context for state, another for dispatch. Components that only send actions (buttons, forms) read the stable dispatch context and don't re-render when the state changes.

  3. What's the purpose of the third argument init in useReducer(reducer, arg, init)?

    Correct answer: Lazy initialization: init(arg) is called only on the first render

    useReducer(reducer, username, createInitialState) avoids recomputing an expensive initial state on every render - like a lazy initializer in useState. init can also be reused to reset the state.

  4. A component uses only theme from a big AppContext but re-renders on every cart update. What helps?

    Correct answer: Split the context into smaller ones by domain and change frequency

    React.memo doesn't stop re-renders caused by a context the component reads. Separate ThemeContext and CartContext limit updates to the consumers that need them. For very frequent updates, use a store with selectors.

All 75 questions with answers →

State Management · Senior

  1. Why do Redux, Zustand and similar libraries subscribe through useSyncExternalStore?

    Correct answer: It guarantees a consistent snapshot during concurrent rendering (no tearing)

    With concurrent rendering React may pause a render; if an external store changes meanwhile, some components could read old values and others new ones. useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) prevents that and supports SSR.

  2. What's the difference between the "subscribe to a selector" model (Redux, Zustand) and Context?

    Correct answer: A store notifies components and each re-renders only if its selected slice changed

    Context has no selectors: any value change re-renders every consumer. Stores run each subscriber's selector and compare results, so updates are fine-grained. Libraries like use-context-selector emulate this on top of Context.

  3. Where should the state of a list filter (search text, sort, page) ideally live in a routed app?

    Correct answer: In the URL search params - shareable, survives reloads and works with back/forward

    The URL is state too. Filters in ?q=&sort=&page= make links shareable and history meaningful, and loaders/query keys can derive from them. Debounce typing and replace (not push) history entries for every keystroke.

  4. Which classification of state helps pick tools in a large app?

    Correct answer: Server cache, URL state, form state, local UI state and global client state

    Each kind has a natural home: server cache - TanStack Query/RTK Query/SWR/loaders; URL - the router; forms - local state or a form library; UI - useState; truly global client state - Context or a store. Putting everything into one store makes it the bottleneck.

All 75 questions with answers →

Combined quizzes with this topic

Questions from several topics at once - just like an interview for a specific role.

Coding tasks

Write your solution right in the browser, and tests check it instantly. Interview classics: debounce, throttle, deepClone, Promise.all, EventEmitter, an LRU cache and more.

Open tasks →