Created
October 25, 2018 20:09
-
-
Save gabemeola/1641c75d82df434bf36035a10869676b to your computer and use it in GitHub Desktop.
Combines Redux reducers with a top level root reducer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Combines reducers with root reducer | |
* | |
* @param {function(Object, Object): Object} rootReducer | |
* @param {Object<string, function(Object, Object): Object>} [reducers={}] | |
* @returns {function(Object, Object): Object} | |
*/ | |
export default function combineReducersWithRoot(rootReducer, reducers = {}) { | |
const entries = Object.entries(reducers); | |
return (state, action) => { | |
const rootState = rootReducer(state, action); | |
// Merge in reducers | |
return entries.reduce((accumulator, [key, fn]) => { | |
// Check if nested state is undefined | |
const reducerState = typeof state !== 'undefined' | |
? state[key] | |
: state; | |
accumulator[key] = fn(reducerState, action); | |
return accumulator; | |
}, { | |
// Root State is the initial reduce value | |
...rootState, | |
}); | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import combineReducersWithRoot from './combineReducersWithRoot'; | |
const initState = { name: 'paypal' } | |
const root = (state = initState, action) => { | |
if (action.type === 'test') { | |
return { | |
...state, | |
name: action.name, | |
} | |
} | |
return state; | |
} | |
it('should merge root reducer', () => { | |
const reducer = combineReducersWithRoot(root); | |
expect(reducer).toBeInstanceOf(Function) | |
expect(reducer(undefined, {})).toEqual(initState) | |
expect(reducer({ ...initState }, { type: 'test', name: 'facebook' })).toEqual({ name: 'facebook' }) | |
}) | |
it('should merge nested reducers', () => { | |
const initStats = { people: 1000 } | |
const statsReducer = (state = initStats, action) => { | |
if (action.type === 'ADD_PEOPLE') { | |
return { | |
...state, | |
people: state.people + action.add, | |
} | |
} | |
return state; | |
} | |
const reducer = combineReducersWithRoot(root, { | |
stats: statsReducer, | |
}) | |
expect(reducer).toBeInstanceOf(Function); | |
expect(reducer(undefined, {})).toEqual({ ...initState, stats: initStats }) | |
expect(reducer({ ...initState, stats: initStats }, { type: 'ADD_PEOPLE', add: 5 })).toEqual({ | |
...initState, | |
stats: { | |
...initStats, | |
people: initStats.people + 5 | |
} | |
}) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment