In the reducer composition pattern, the same steps are taken by the rootReducer
for each slice reducer:
- call the slice reducer with its slice of the
state
and theaction
as arguments - store the returned slice of state in a new object that is ultimately returned by the
rootReducer()
.
import { createStore } from 'redux'; // todosReducer and filterReducer omitted const rootReducer = (state = {}, action) => { const nextState = { todos: todosReducer(state.todos, action), filter: filterReducer(state.filter, action) }; return nextState; }; const store = createStore(rootReducer);
The Redux package helps facilitate this pattern by providing a utility function called combineReducers()
which handles this boilerplate for us:
import { createStore, combineReducers } from 'redux' // todosReducer and filterReducer omitted. const reducers = { todos: todosReducer, filter: filterReducer }; const rootReducer = combineReducers(reducers); const store = createStore(rootReducer);
Let’s break this code down:
- The
reducers
object contains the slice reducers for the application. The keys of the object correspond to the name of the slice being managed by the reducer value. - The
combineReducers()
function accepts thisreducers
object and returns arootReducer
function. - The returned
rootReducer
is passed tocreateStore()
to create astore
object.
Just as before, when an action is dispatched to the store
, the rootReducer()
is executed which then calls each slice reducer, passing along the action
and the appropriate slice of state
.
The last 6 lines of this example can be rewritten inline:
const store = createStore(combineReducers({ todos: todosReducer, filter: filterReducer }));
Take a look at store.js where you will find the slice reducers that you created in the last exercise. Now, however, the rootReducer()
is missing. Rather than creating this function by hand, you will use combineReducers()
.
Instructions
First, at the top of store.js, import combineReducers
from the redux
library.
combineReducers()
accepts an object of reducers as its argument. Let’s create one!
At the bottom of store.js, create a variable called reducers
. Assign to it an object with three properties: allRecipes
, favoriteRecipes
, searchTerm
. Each property should be assigned its associated slice reducer.
Now, declare another variable called rootReducer
. Call combineReducers()
with the reducers
object as an argument and assign the returned value to rootReducer
.
Finally, pass the rootReducer
to the createStore()
function and save the returned value in a new variable called store
.