Enter Your Email Address to Watch This Lesson

Your link to unlock this lesson will be sent to this email address.

Unlock this lesson and all 1023 of the free egghead.io lessons, plus get JavaScript content delivered directly to your inbox!



Existing egghead members will not see this. Sign in.

Redux: Reducer Composition with combineReducers()

2:10 JavaScript lesson by

Learn how to use combineReducers() utility function to generate a reducer from several other reducers instead of writing it by hand.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

Learn how to use combineReducers() utility function to generate a reducer from several other reducers instead of writing it by hand.

Avatar
Boris

Can we use combineReducers() several times in the "nested" reducers or is it just here to create the top level reducer ?

Avatar
Dan Abramov

Boris,

You can absolutely use combineReducers() multiple times. In fact "shopping cart" example in Redux repo does that.

In reply to Boris

In the previous lesson we learned how to use the reducer composition pattern to let different reducers handle different parts of the state tree, and then combine their results.

This pattern is so common that it's present in most Redux applications. This is why Redux provides a function called combineReducers that lets you avoid writing this code by hand. Instead, it generates the top level reducer for you.

const { combineReducers } = Redux;
const todoApp = combineReducers({
  todos: todos,
  visibilityFilter: visibilityFilter
});

The only argument to combine reducers is an object. This object lets me specify the mapping between the state field names, and the reducers managing them. The return value of the combineReducer is called a Reducer function, which is pretty much equivalent to the reducer function I wrote by hand previously.

The keys of the object I configure combinedReducers with correspond to the fields that the state object is going to manage. The values of the object I have asked to combineReducer, are the producers we should call to update the correspondence state fields.

const todos = (state = [], action) => {
  switch (action.type) { ... }
};

const visibilityFilter = (
  state = 'SHOW_ALL',
  action
) => {
  switch (action.type) { ... }
};

This combineReducer call says that the todo's field inside the state object managers will be updated by the todos reducer, and the visibilityFilter field inside the state object will be updated by calling the visibilityFilter reducer. The results will be assembled into a single object. In other words, it behaves pretty much exactly as the function commented down below.

//  const todoApp = (state = {}, action) => {
//    return {
//      todos: todos(
//       state.todos,
//        action
//     ),
//      visibilityFilter: visibilityFilter(
//        state.visibilityFilter,
//        action
//      )
//    };
//  };

Finally, I will establish a useful convention. I will always name my reducers after the state keys they manage. Since the key names and the value names are now the same, I can omit the values thanks to the ES6 object literal shorthand notation.

const todoApp = combineReducers({
  todos,
  visibilityFilter
});

In this lesson, you learned how to generate a simple reducer that calls many reducers to manage parts of its state by using the combineReducers utility function.

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?