Update application state in response to actions
Handle domain events
Redux Toolkit · Type Alias
A reducer is a pure function that maps current state and an action to the next state. Redux Toolkit commonly creates reducers with createSlice, where Immer enables concise immutable update logic.
A reducer is a pure function that receives the current state and an action, determines whether that action applies, and returns the next state. Redux Toolkit commonly generates reducers with createSlice; its case reducers may use mutation-style code because Immer produces immutable updates.
(state, action) => newState| Name | Type | Description |
|---|---|---|
state | State | The current state value being reduced. |
action | Action | The dispatched action object used to determine the update. |
The next state value.
import { createSlice, type PayloadAction } from '@reduxjs/toolkit'
type CounterState = { value: number }
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 } satisfies CounterState,
reducers: {
increment(state) {
state.value += 1
},
add(state, action: PayloadAction<number>) {
state.value += action.payload
},
},
})
export const { increment, add } = counterSlice.actions
export default counterSlice.reducerThis creates a slice reducer whose case reducers receive state and actions. Redux Toolkit uses Immer so the apparent mutation is converted into an immutable update.
Handle domain events
Organize feature state
Compose state logic
A reducer takes the previous state and an action, then returns the next state. It should calculate that result only from those arguments and must not perform side effects.
Follow-up: What should happen when an action is irrelevant? Return the current state unchanged rather than creating an unrelated update.
Redux Toolkit's createSlice and createReducer use Immer internally. This permits mutation-like statements inside their case reducers while Immer creates the correct immutable result.
Follow-up: Would the same mutation syntax be safe in a hand-written Redux reducer? No; outside Immer, the original state must not be mutated.
A reducer can be written as a switch over action.type, checking whether each action is relevant and returning a copied, updated state when it is. Redux Toolkit generally reduces this boilerplate through createSlice and named case reducers.
Follow-up: How are generated action types kept distinct? createSlice prefixes generated action types with the slice name.
createSlicecreateReducercreateActioncombineReducersPayloadActionconfigureStore