Redux

Updated 3 min read index source
On this page4
  1. Files
  2. The shape of modern Redux
  3. Does your project need Redux?
  4. Interview angle

Redux

A predictable state container: one store, state changed only by dispatching actions, reducers that are pure functions of (state, action). Everything Redux does follows from those three rules.

Write new Redux with Redux Toolkit. Hand-written action-type constants, action creators and switch reducers are the pattern RTK replaced, and the official documentation says so. The older style is worth recognising because you will read it, not because you should write it.

Files

File Covers
Redux Todo App Guide the three principles, the classic hand-written style you will meet in legacy code
Redux Toolkit Todo App Guide createSlice, configureStore, Immer, createAsyncThunk - the current way
RTK Query caching, deduplication and invalidation for server data
Dispatch Function in Redux what dispatch does, useDispatch, why actions must be serialisable
Selectors in Redux encapsulating state shape, why useSelector re-renders too often
Reselect in Redux memoized derived state, the cache-size-1 problem and what Reselect 5 changed
Redux Middleware the store => next => action chain, where side effects live
Synchronous vs Asynchronous Middleware in Redux how thunks work, ordering, cancelling in-flight work
mapStateToProps in Redux legacy connect API - for reading existing code
mapDispatchToProps in Redux legacy connect API - for reading existing code

The shape of modern Redux

js
import { createSlice, configureStore } from '@reduxjs/toolkit';

const todos = createSlice({
  name: 'todos',
  initialState: { items: [], filter: 'all' },
  reducers: {
    added(state, action) { state.items.push(action.payload); },  // Immer draft
    filtered(state, action) { state.filter = action.payload; },
  },
});

export const { added, filtered } = todos.actions;
export const store = configureStore({ reducer: { todos: todos.reducer } });

createSlice generates the action types, action creators and reducer from one object. The apparently mutating code is Immer running against a draft proxy and producing an immutable next state — it only works inside createSlice/createReducer, and the same code elsewhere really does mutate.

In components, use the hooks: useSelector to read, useDispatch to dispatch. connect with mapStateToProps/mapDispatchToProps is the legacy API kept for class components.

Does your project need Redux?

Often not, and being able to say so is the stronger answer.

State Where it belongs
Server data a query library — RTK Query, TanStack Query. It owns caching, deduplication, revalidation and invalidation.
Form state a form library, or local component state
UI state used by one subtree component state, or context
Genuinely global client state with complex transitions Redux, or a smaller store like Zustand

Redux earns its place when you need a large shared state graph, strict traceability of every change, or time-travel debugging on a big team. It does not earn its place as a hand-written cache for fetched data — see Server State vs Client State and Choosing a State Library.

Interview angle 5

  • “What are Redux’s three principles?” - single source of truth, state is read-only and changed only by dispatching actions, and changes are made by pure reducers. Everything else follows.
  • “Why must reducers be pure?” - predictability, replayability and time-travel debugging. A reducer that fetches, mutates its argument or reads the clock makes the same action produce different state, breaking all three.
  • “How can RTK reducers look like they mutate?” - Immer. The reducer runs against a draft proxy and RTK derives the immutable next state from the recorded changes.
  • “Why does my component re-render on every store change?” - useSelector compares with ===, so a selector returning a new object or the result of .map/.filter fails the check every time. Select primitives, pass shallowEqual, or memoize with Reselect.
  • “Would you choose Redux for a new project?” - only if the state is genuinely global, complex and needs auditability. Server data goes in a query library and modest client state in component state or Zustand. Reaching for Redux by default in 2026 is the answer that invites pushback.

Contents 10