Beyond combineReducers

    The common question, then, is "How can I use combineReducers to handle these other use cases?". The answer to that is simply: "you don't - you probably need to use something else". Once you go past the core use case for combineReducers, it's time to use more "custom" reducer logic, whether it be specific logic for a one-off use case, or a reusable function that could be widely shared. Here's some suggestions for dealing with a couple of these typical use cases, but feel free to come up with your own approaches.

    Since combineReducers currently only works with plain Javascript objects, an application that uses an Immutable.js Map object for the top of its state tree could not use combineReducers to manage that Map. Since many developers do use Immutable.js, there are a number of published utilities that provide equivalent functionality, such as redux-immutable. This package provides its own implementation of combineReducers that knows how to iterate over an Immutable Map instead of a plain Javascript object.

    Similarly, if happens to need some data from sliceReducerB's slice of state in order to handle a particular action, or sliceReducerB happens to need the entire state as an argument, combineReducers does not handle that itself. This could be resolved by writing a custom function that knows to pass the needed data as an additional argument in those specific cases, such as:

    Because the data from B's slice is already in the action, the parent reducer doesn't have to do anything special to make that data available to sliceReducerA.

    A third approach would be to use the reducer generated by combineReducers to handle the "simple" cases where each slice reducer can update itself independently, but also use another reducer to handle the "special" cases where data needs to be shared across slices. Then, a wrapping function could call both of those reducers in turn to generate the final result:

    As it turns out, there's a useful utility called that can make that process easier. It simply takes multiple reducers and runs on them, passing the intermediate state values to the next reducer in line:

    Again, it's important to understand that Redux reducers are just functions. While combineReducers is useful, it's just one tool in the toolbox. Functions can contain conditional logic other than switch statements, functions can be composed to wrap each other, and functions can call other functions. Maybe you need one of your slice reducers to be able to reset its state, and to only respond to specific actions overall. You could do:

    Note that combineReducers doesn't know or care that there's anything special about the reducer function that's responsible for managing a. We didn't need to modify combineReducers to specifically know how to undo things - we just built up the pieces we needed into a new composed function.

    Also, while is the one reducer utility function that's built into Redux, there's a wide variety of third-party reducer utilities that have published for reuse. The Redux Addons Catalog lists many of the third-party utilities that are available. Or, if none of the published utilities solve your use case, you can always write a function yourself that does just exactly what you need.