Skip to content

Commit 9e5a1b0

Browse files
committed
feat(default): support path function in subpathReducer
1 parent 5270770 commit 9e5a1b0

File tree

3 files changed

+21
-3
lines changed

3 files changed

+21
-3
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ import {subpathReducer} from 'mindfront-redux-utils-immutable'
8585

8686
```es6
8787
function subpathReducer(
88-
path: Array<any>,
88+
path: Array<any> | (action: Action) => Array<any>,
8989
initialState?: Immutable.Collection.Keyed | Record
9090
): Reducer => Reducer
9191
```
@@ -94,4 +94,7 @@ Creates a reducer that applies the decorated reducer at the given `path` within
9494
equivalent to `(state = initialState, action) => state.updateIn(path, reducer)` except that if the decorated reducer
9595
has `actionHandlers`, the created reducer will have corresponding `actionHandlers` so that other utils can optimize it.
9696

97+
If you pass a function for `path`, `subpathReducer` will get the actual path by calling `path(action)` for each
98+
`action`.
99+
97100

src/subpathReducer.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@ import {createReducer} from 'mindfront-redux-utils'
22
import mapValues from 'lodash.mapvalues'
33

44
export default function subpathReducer(subpath, initialState) {
5+
if (typeof subpath !== 'function') {
6+
const fixedSubpath = subpath
7+
subpath = () => fixedSubpath
8+
}
59
return reducer => {
610
const {actionHandlers} = reducer
711
if (actionHandlers instanceof Object) {
812
const initialSubState = reducer.initialState
913
return createReducer(initialState, mapValues(actionHandlers, reducer => (state, action) =>
10-
state.updateIn(subpath, (substate = initialSubState) => reducer(substate, action))
14+
state.updateIn(subpath(action), (substate = initialSubState) => reducer(substate, action))
1115
))
1216
}
1317
return (state = initialState, action) =>
14-
state.updateIn(subpath, substate => reducer(substate, action))
18+
state.updateIn(subpath(action), substate => reducer(substate, action))
1519
}
1620
}
1721

test/subpathReducerTest.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,16 @@ describe('subpathReducer', () => {
2727
expect(reducer(undefined, {type: 'INCREMENT'})).to.equal(fromJS({a: {b: 1}}))
2828
expect(reducer(fromJS({a: {b: 2}}), {type: 'INCREMENT'})).to.equal(fromJS({a: {b: 3}}))
2929
})
30+
it("calls subpath with action if it's a function", () => {
31+
const reducer = subpathReducer(action => action.meta.reduxPath, Map())(createReducer(0, {
32+
INCREMENT: state => state + 1
33+
}))
34+
35+
expect(reducer.actionHandlers.INCREMENT).to.be.an.instanceof(Function)
36+
37+
expect(reducer(undefined, {})).to.equal(fromJS({}))
38+
expect(reducer(undefined, {type: 'INCREMENT', meta: {reduxPath: ['a', 'b']}})).to.equal(fromJS({a: {b: 1}}))
39+
expect(reducer(fromJS({a: 2}), {type: 'INCREMENT', meta: {reduxPath: ['a']}})).to.equal(fromJS({a: 3}))
40+
})
3041
})
3142

0 commit comments

Comments
 (0)