Redux

Redux is a predictable state-management library for JavaScript apps — most associated with React, but usable anywhere. It puts all your application state in a single store, and the only way to change it is to dispatch an action describing what happened, which a pure reducer function turns into the next state. That one-way, explicit flow makes state changes traceable, debuggable, and testable.

Redux dominated React state management for years, became a byword for boilerplate, and then reinvented itself: Redux Toolkit (RTK) is now the official, batteries-included way to write Redux, cutting the ceremony dramatically. Understanding Redux matters both because a huge amount of production code uses it and because its ideas (immutable updates, actions, the reducer pattern) shaped the whole ecosystem — see State Management for the broader landscape.

TL;DR

Quick Example

Modern Redux with Redux Toolkit — a slice, the store, and a component:

Compare this to classic Redux (action type constants, action creators, switch-statement reducers, mapStateToProps) and the RTK improvement is obvious — same architecture, a fraction of the code.

Core Concepts

The Three Principles

Redux rests on three rules that produce its predictability:

  1. Single source of truth — all state lives in one store (a plain object tree).
  2. State is read-only — you never mutate it; you dispatch an action to request a change.
  3. Changes via pure reducers(state, action) => newState, with no side effects, so the same inputs always give the same output.

Because every change is an explicit, serializable action run through a pure function, you get time-travel debugging (replay actions), trivial testing (call the reducer with inputs, assert output), and a complete audit of what happened and when.

Store, Actions, Reducers, Selectors

Redux Toolkit: How Redux Is Actually Written

RTK exists because classic Redux made you write the same boilerplate endlessly. It provides:

The official guidance is unambiguous: use RTK. Hand-written classic Redux is legacy — you'll read it, but you shouldn't write new code that way.

RTK Query: Data Fetching

RTK Query (part of RTK) handles server data — fetching, caching, invalidation, loading states — declaratively:

This overlaps heavily with React Query/TanStack Query — an important point below.

When You Actually Need Redux

The most valuable Redux knowledge is when not to use it. Redux adds structure and ceremony that pays off only for certain problems:

Reach for Redux when:

Skip Redux (use lighter tools) when:

The industry has broadly moved from "Redux by default" to "Redux when the complexity justifies it," with Zustand and server-state libraries absorbing the cases Redux was overkill for. See State Management for the full comparison.

Common Mistakes

Writing Classic Redux in 2026

Action-type constants, hand-written action creators, switch-statement reducers, connect/mapStateToProps — this is the boilerplate RTK eliminated. New Redux code should be createSlice + hooks. If a tutorial has you writing const INCREMENT = "INCREMENT", it's outdated.

Putting Server Data in Redux Manually

Fetching in thunks and hand-managing loading/error/cache state in the store is reinventing (badly) what RTK Query and React Query do. Server state and client state are different problems — use a data-fetching library for the former.

Reaching for Redux Reflexively

Adding Redux to a small app "because that's what you do with React" imposes real overhead for no benefit. Start with local state and Context; adopt Redux (or Zustand) when you feel the actual pain of complex shared state.

Mutating State Outside Immer

Classic reducers must return new objects ({ ...state, value: ... }); mutating directly breaks Redux silently. RTK's Immer lets you write mutations inside createSlice only — mutating state elsewhere is still a bug.

Over-normalizing or Under-normalizing

Deeply nested state is painful to update; RTK's createEntityAdapter provides normalized storage for collections. But normalizing trivial state adds complexity for nothing — match the structure to the actual data shape.

FAQ

Is Redux dead?

No — but it's no longer the default. It powers enormous amounts of production code, RTK made it far pleasanter, and it remains the right tool for genuinely complex shared state. What died is "Redux for everything"; it's now one option among several (Zustand, Jotai, Context, server-state libraries), chosen when its structure earns its cost.

Redux Toolkit vs classic Redux?

RTK is classic Redux with the boilerplate removed and best practices built in — same architecture and mental model, dramatically less code, plus Immer, DevTools, and thunks preconfigured. There is no reason to write classic Redux for new code; the Redux team itself says use RTK.

Redux or Zustand?

Zustand is a much lighter global-state library (a hook-based store, minimal boilerplate, no providers) that covers many cases Redux was overused for. Choose Redux when you want its strict structure, ecosystem, DevTools time-travel, or already use it; choose Zustand for simpler global state without the ceremony. Both are excellent.

Redux or React Query?

They solve different problems and often coexist. React Query/TanStack Query manages server state (fetching, caching, sync). Redux manages client state (UI state, complex app logic). Many apps use React Query for data and a little Redux/Zustand for the rest. Don't use Redux as a manual server cache.

Do I need to learn Redux?

Worth understanding because so much code uses it and its concepts (unidirectional flow, reducers, immutability) are foundational. But learn modern RTK, and learn the alternatives too — knowing when to use Redux is more valuable than deep Redux mechanics.

Related Topics

References