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.
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.
https://redux-toolkit.js.org/api/createReducer#builder-methods