If you have only one reducer, you do not need to combineReducers() . Just use it directly:
const initialState = { sources: [], left: {}, right: {} } function app(state = initialState, action) { switch (action.type) { case 'ADD_SOURCE': return Object.assign({}, state, { sources: [...state.sources, action.newSource] }) case 'ADD_SOURCE_TO_LEFT': return Object.assign({}, state, { left: Object.assign({}, state.left, { [action.sourceId]: true }) }) case 'ADD_SOURCE_TO_RIGHT': return Object.assign({}, state, { right: Object.assign({}, state.right, { [action.sourceId]: true }) }) default: return state } }
Now you can create a store with this gear:
import { createStore } from 'redux' const store = createStore(app)
And connect the component to it:
const mapStateToProps = (state) => ({ sources: state.sources })
However, your gearbox is hard to read because it updates several different things at once. Now this is the moment when you want to split it into several independent gearboxes:
function sources(state = [], action) { switch (action.type) { case 'ADD_SOURCE': return [...state.sources, action.newSource] default: return state } } function left(state = {}, action) { switch (action.type) { case 'ADD_SOURCE_TO_LEFT': return Object.assign({}, state, { [action.sourceId]: true }) default: return state } } function right(state = {}, action) { switch (action.type) { case 'ADD_SOURCE_TO_RIGHT': return Object.assign({}, state, { [action.sourceId]: true }) default: return state } } function app(state = {}, action) { return { sources: sources(state.sources, action), left: left(state.left, action), right: right(state.right, action), } }
This is easier to maintain and understand, and also makes it easy to modify and test gearboxes independently.
Finally, as a last step, we can use combineReducers() to generate the root reducer app instead of writing it manually:
// function app(state = {}, action) { // return { // sources: sources(state.sources, action), // left: left(state.left, action), // right: right(state.right, action), // } // } import { combineReducers } from 'redux' const app = combineReducers({ sources, left, right })
There is not much benefit from using combineReducers() instead of writing the root reducer manually, except that it is a little more efficient and is likely to save you a few typos. In addition, you can apply this template several times in your application: its subtlety for combining unconnected gearboxes into one gearbox several times in a nested manner.
All this refactoring will not affect the components.
I suggest you look at my free Egghead course on Redux , which covers this reduction composition pattern and shows how combineReducers() implemented.