QuickTip: Writing Shared (common) reducer actions in redux-toolkit
Handling old redux patterns with modern redux
Table of contents
Context
The modern way to write redux is through redux-toolkit as recommended by redux maintainers.
In redux toolkit we write slice which contains the reducer and the actions for a particular feature. The actions are generated by redux toolkit here and they are by default scoped to their reducer.
As a redux user, you must have come across the use-case where you need an action to trigger update to more than one reducers and update the state. For e.g. User login or Navigation change.
Implementing a shared action in redux toolkit
Start by defining the action outside the slice using createAction
, preferably in a separate file of common actions.
import { createAction } from "@reduxjs/toolkit";
export const commonAction = createAction("commonAction");
To use this action within any reducer, we need to use extraReducers
in that specific reducer
Similar to
createReducer
, theextraReducers
field uses a "builder callback" notation to define handlers for specific action types, matching against a range of actions, or handling a default case.
Let's add the commonAction
action in a reducer
const counterSlice = createSlice({
name: "counter",
initialState: counterInitialState,
reducers: {
... // general reducer actions
extraReducers: (builder) => {
builder.addCase(commonAction, (state, action) => {
console.log("common action from counter", state.count, action.payload);
state.count = action.payload;
});
},
});
Now, when the commonAction is dispatched from anywhere in the app, counterSlice's reducer will be able to handle it.
Here, we are using addCase
to add the particular common/shared action. We also have addMatcher
and addDefaultCase
.
With addMatcher
we can write our own filter function that determines whether the incoming action should match, which is usually determined just by the action.type.
With addDefaultCase
we can handle a default case when no other actions matched in the reducer.
Links
https://redux-toolkit.js.org/api/createReducer#builder-methods
https://gist.github.com/gzamann/d4b06e67a4aa48e21454f725f234f342