Created
March 13, 2017 00:53
-
-
Save vmasto/c434c23929035cbe23e99dc14fee4147 to your computer and use it in GitHub Desktop.
Reducer Extensions
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
| /** | |
| * A higher order function that takes a reducer and an extension | |
| * and returns a reducer amplified with provided extensions on | |
| * existing or new action types. | |
| * | |
| * Extensions are objects containing the action `type` attribute | |
| * and an `actionTypeExtension` function which takes `state` and | |
| * the `action` and must return an object to append to the reducer's | |
| * new state. | |
| * | |
| * Example of an extension: | |
| * { | |
| * type: ACTION_SUCCESS, | |
| * actionTypeExtension: (state, action) => ({ | |
| * foo: action.payload.foo | |
| * }) | |
| * } | |
| * | |
| * @param {Function} reducer - The reducer to extend | |
| * @param {Array<Object>} extensions - An array of extensions actions | |
| * with which to amplify the reducer | |
| * | |
| * @returns {Function} - The extended reducer | |
| */ | |
| const extendedReducer = (reducer, extensions) => (state, action) => { | |
| if (!extensions || !action) { | |
| return reducer(state, action); | |
| } | |
| const { type } = action; | |
| const extension = extensions.find(x => x.type === type); | |
| if (extension && extension.type === type) { | |
| if (typeof extension.actionTypeExtension !== 'function') { | |
| throw new Error('Expecting extension to contain an `actionTypeExtension` method.'); | |
| } | |
| return { | |
| ...reducer(state, action), | |
| ...extension.actionTypeExtension(state, action), | |
| }; | |
| } | |
| return reducer(state, action); | |
| }; | |
| export default extendedReducer; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment