Skip to content

Commit 7f301d7

Browse files
committed
Merge pull request #1329 from rackt/bind-action-creators-1
Object returned from bindActionCreators() should only include functions
2 parents 29468b8 + 47d0024 commit 7f301d7

File tree

7 files changed

+52
-77
lines changed

7 files changed

+52
-77
lines changed

src/bindActionCreators.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import mapValues from './utils/mapValues'
2-
31
function bindActionCreator(actionCreator, dispatch) {
42
return (...args) => dispatch(actionCreator(...args))
53
}
@@ -30,14 +28,21 @@ export default function bindActionCreators(actionCreators, dispatch) {
3028
return bindActionCreator(actionCreators, dispatch)
3129
}
3230

33-
if (typeof actionCreators !== 'object' || actionCreators === null || actionCreators === undefined) {
31+
if (typeof actionCreators !== 'object' || actionCreators === null) {
3432
throw new Error(
3533
`bindActionCreators expected an object or a function, instead received ${actionCreators === null ? 'null' : typeof actionCreators}. ` +
3634
`Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
3735
)
3836
}
3937

40-
return mapValues(actionCreators, actionCreator =>
41-
bindActionCreator(actionCreator, dispatch)
42-
)
38+
var keys = Object.keys(actionCreators)
39+
var boundActionCreators = {}
40+
for (var i = 0; i < keys.length; i++) {
41+
var key = keys[i]
42+
var actionCreator = actionCreators[key]
43+
if (typeof actionCreator === 'function') {
44+
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
45+
}
46+
}
47+
return boundActionCreators
4348
}

src/combineReducers.js

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import { ActionTypes } from './createStore'
22
import isPlainObject from './utils/isPlainObject'
3-
import mapValues from './utils/mapValues'
4-
import pick from './utils/pick'
53
import warning from './utils/warning'
64

75
function getUndefinedStateErrorMessage(key, action) {
@@ -92,11 +90,18 @@ function assertReducerSanity(reducers) {
9290
* @returns {Function} A reducer function that invokes every reducer inside the
9391
* passed object, and builds a state object with the same shape.
9492
*/
95-
9693
export default function combineReducers(reducers) {
97-
var finalReducers = pick(reducers, (val) => typeof val === 'function')
98-
var sanityError
94+
var reducerKeys = Object.keys(reducers)
95+
var finalReducers = {}
96+
for (var i = 0; i < reducerKeys.length; i++) {
97+
var key = reducerKeys[i]
98+
if (typeof reducers[key] === 'function') {
99+
finalReducers[key] = reducers[key]
100+
}
101+
}
102+
var finalReducerKeys = Object.keys(finalReducers)
99103

104+
var sanityError
100105
try {
101106
assertReducerSanity(finalReducers)
102107
} catch (e) {
@@ -116,17 +121,19 @@ export default function combineReducers(reducers) {
116121
}
117122

118123
var hasChanged = false
119-
var finalState = mapValues(finalReducers, (reducer, key) => {
124+
var nextState = {}
125+
for (var i = 0; i < finalReducerKeys.length; i++) {
126+
var key = finalReducerKeys[i]
127+
var reducer = finalReducers[key]
120128
var previousStateForKey = state[key]
121129
var nextStateForKey = reducer(previousStateForKey, action)
122130
if (typeof nextStateForKey === 'undefined') {
123131
var errorMessage = getUndefinedStateErrorMessage(key, action)
124132
throw new Error(errorMessage)
125133
}
134+
nextState[key] = nextStateForKey
126135
hasChanged = hasChanged || nextStateForKey !== previousStateForKey
127-
return nextStateForKey
128-
})
129-
130-
return hasChanged ? finalState : state
136+
}
137+
return hasChanged ? nextState : state
131138
}
132139
}

src/utils/mapValues.js

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/utils/pick.js

Lines changed: 0 additions & 15 deletions
This file was deleted.

test/bindActionCreators.spec.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,24 @@ import * as actionCreators from './helpers/actionCreators'
55

66
describe('bindActionCreators', () => {
77
let store
8+
let actionCreatorFunctions
89

910
beforeEach(() => {
1011
store = createStore(todos)
12+
actionCreatorFunctions = { ...actionCreators }
13+
Object.keys(actionCreatorFunctions).forEach(key => {
14+
if (typeof actionCreatorFunctions[key] !== 'function') {
15+
delete actionCreatorFunctions[key]
16+
}
17+
})
1118
})
1219

1320
it('wraps the action creators with the dispatch function', () => {
1421
const boundActionCreators = bindActionCreators(actionCreators, store.dispatch)
1522
expect(
1623
Object.keys(boundActionCreators)
1724
).toEqual(
18-
Object.keys(actionCreators)
25+
Object.keys(actionCreatorFunctions)
1926
)
2027

2128
const action = boundActionCreators.addTodo('Hello')
@@ -27,6 +34,22 @@ describe('bindActionCreators', () => {
2734
])
2835
})
2936

37+
it('skips non-function values in the passed object', () => {
38+
const boundActionCreators = bindActionCreators({
39+
...actionCreators,
40+
foo: 42,
41+
bar: 'baz',
42+
wow: undefined,
43+
much: {},
44+
test: null
45+
}, store.dispatch)
46+
expect(
47+
Object.keys(boundActionCreators)
48+
).toEqual(
49+
Object.keys(actionCreatorFunctions)
50+
)
51+
})
52+
3053
it('supports wrapping a single function only', () => {
3154
const actionCreator = actionCreators.addTodo
3255
const boundActionCreator = bindActionCreators(actionCreator, store.dispatch)

test/utils/mapValues.spec.js

Lines changed: 0 additions & 16 deletions
This file was deleted.

test/utils/pick.spec.js

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)