Structuring Reducers
This page describes the low-level Redux mechanism that Redux Toolkit builds on. In an application, you would normally use Redux Toolkit's configureStore and createSlice rather than writing this code yourself. It's still worth understanding what they do underneath.
To learn how to write Redux apps today, see the Redux Essentials tutorial. To update existing code, see Migrating to Modern Redux.
At its core, Redux is really a fairly simple design pattern: all your "write" logic goes into a single function, and the only way to run that logic is to give Redux a plain object that describes something that has happened. The Redux store calls that write logic function and passes in the current state tree and the descriptive object, the write logic function returns some new state tree, and the Redux store notifies any subscribers that the state tree has changed.
Redux puts some basic constraints on how that write logic function should work. As described in "Redux Fundamentals" Part 3: State, Actions, and Reducers, it has to have a signature of (previousState, action) => newState, is known as a reducer function, and must be pure and predictable.
Beyond that, Redux does not really care how you actually structure your logic inside that reducer function, as long as it obeys those basic rules. This is both a source of freedom and a source of confusion. However, there are a number of common patterns that are widely used when writing reducers, as well as a number of related topics and concepts to be aware of. As an application grows, these patterns play a crucial role in managing reducer code complexity, handling real-world data, and optimizing UI performance.
The pages in this section show these patterns written by hand, with switch statements and object spreads. Redux Toolkit's createSlice implements the same patterns: each "case function" becomes an entry in its reducers object, the immutable update logic is handled by Immer, and configureStore combines the resulting slice reducers for you. Read the pages here to understand what createSlice is doing, then write your own reducers with it.
Prerequisite Concepts for Writing Reducers
Some of these concepts are already described elsewhere in the Redux documentation. Others are generic and applicable outside of Redux itself, and there are numerous existing articles that cover these concepts in detail. These concepts and techniques form the foundation of writing solid Redux reducer logic.
It is vital that these Prerequisite Concepts are thoroughly understood before moving on to more advanced and Redux-specific techniques. A recommended reading list is available at:
Prerequisite Concepts
Standard Redux architecture relies on using plain JS objects and arrays for your state. If you're using an alternate approach for some reason, the details may differ based on your approach, but many of the principles will still apply.