/ Reduce

Reduce the Reducers!

Currently I have the great fortune of getting to work on a project using React and Redux on the front end. This is not, however, a post about why I am finding this a wonderful and fun ecosystem to work in. There are enough of those around the web. I just wanted to give a quick view of how Redux’s combineReducers function works as a reference for those starting out with it. (Though you might expect a full teardown of this function to appear soon…)

CombineReducers enables you to break your Redux store apart into categories each handled by their own reducer. While not necessary to use Redux this allows you to compartmentalize your store in the same way you do your React components, with the same obvious benefits. (Though do not take this to mean that you should break up your store based on your components). The idea is that rather than having one single reducer that balloons in size you can make a separate reducer for each section of your state. The setup is incredibly simple:

import { combineReducers } from 'redux';
import { reducer as form } from 'redux-form';
import folders from './foldersReducer';
import tags from './tagsReducer';
import userPics from './userPicsReducer';
import viewing from './viewingReducer';

const reducer = combineReducers({
  folders,
  tags,
  userPics,
  viewing,
  form,
});
export default reducer;

Each reducer gets passed into the combineReducers call as a property of the parameter object. Redux then returns a new reducer function containing your many reducers which is handed to the store as its top level reducer. Then what? Well you build out each of those reducers to handle and return just their updated part of the sate like you might build a reducer to handle your entire state. That’s it! Almost like magic, but its not, it’s just reduce! CombineReducers encloses each of your reducers and calls reduce on the group every time you dispatch an action to the store.

function combineReducers(reducers) ={
  return (action) => {
    return Object.keys(reducers).reducer((newState, reducer) => {
      state[reducer] = reducers[reducer](action);
    }, {};
  }
}

The result of each of your reducers is contained as one property on your global state object and can be accessed accordingly when mapping your state to properties. This is why it is incredibly important that you adhere to the practice of having a default in each reducer that simple returns the last state. When you dispatch an action it is for one portion of the state, and that reducer will take that action and return the new version of its portion of the state. Each other reducer must return their existing state or your updated global state will be all but empty.

The best part, that snippet above is the core essence of how combineReducers works. Just one of the many examples of Redux’s beautiful simplicity. Alright, maybe this was a little bit about how much fun React/Redux is. ;)