Skip to content

Commit ea43078

Browse files
awearygaearon
authored andcommitted
Only warn for unexpected key once per key (#1818)
Create key cache in combineReducers Only define unexpectedKeyCache in dev environment
1 parent cefb03a commit ea43078

File tree

2 files changed

+41
-9
lines changed

2 files changed

+41
-9
lines changed

src/combineReducers.js

+14-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function getUndefinedStateErrorMessage(key, action) {
1212
)
1313
}
1414

15-
function getUnexpectedStateShapeWarningMessage(inputState, reducers, action) {
15+
function getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {
1616
var reducerKeys = Object.keys(reducers)
1717
var argumentName = action && action.type === ActionTypes.INIT ?
1818
'preloadedState argument passed to createStore' :
@@ -34,7 +34,14 @@ function getUnexpectedStateShapeWarningMessage(inputState, reducers, action) {
3434
)
3535
}
3636

37-
var unexpectedKeys = Object.keys(inputState).filter(key => !reducers.hasOwnProperty(key))
37+
var unexpectedKeys = Object.keys(inputState).filter(key =>
38+
!reducers.hasOwnProperty(key) &&
39+
!unexpectedKeyCache[key]
40+
)
41+
42+
unexpectedKeys.forEach(key => {
43+
unexpectedKeyCache[key] = true
44+
})
3845

3946
if (unexpectedKeys.length > 0) {
4047
return (
@@ -101,6 +108,10 @@ export default function combineReducers(reducers) {
101108
}
102109
var finalReducerKeys = Object.keys(finalReducers)
103110

111+
if (process.env.NODE_ENV !== 'production') {
112+
var unexpectedKeyCache = {}
113+
}
114+
104115
var sanityError
105116
try {
106117
assertReducerSanity(finalReducers)
@@ -114,7 +125,7 @@ export default function combineReducers(reducers) {
114125
}
115126

116127
if (process.env.NODE_ENV !== 'production') {
117-
var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action)
128+
var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache)
118129
if (warningMessage) {
119130
warning(warningMessage)
120131
}

test/combineReducers.spec.js

+27-6
Original file line numberDiff line numberDiff line change
@@ -210,24 +210,24 @@ describe('Utils', () => {
210210
/Unexpected key "bar".*createStore.*instead: "foo", "baz"/
211211
)
212212

213-
createStore(reducer, { bar: 2, qux: 4 })
213+
createStore(reducer, { bar: 2, qux: 4, thud: 5 })
214214
expect(spy.calls[1].arguments[0]).toMatch(
215-
/Unexpected keys "bar", "qux".*createStore.*instead: "foo", "baz"/
215+
/Unexpected keys "qux", "thud".*createStore.*instead: "foo", "baz"/
216216
)
217217

218218
createStore(reducer, 1)
219219
expect(spy.calls[2].arguments[0]).toMatch(
220220
/createStore has unexpected type of "Number".*keys: "foo", "baz"/
221221
)
222222

223-
reducer({ bar: 2 })
223+
reducer({ corge: 2 })
224224
expect(spy.calls[3].arguments[0]).toMatch(
225-
/Unexpected key "bar".*reducer.*instead: "foo", "baz"/
225+
/Unexpected key "corge".*reducer.*instead: "foo", "baz"/
226226
)
227227

228-
reducer({ bar: 2, qux: 4 })
228+
reducer({ fred: 2, grault: 4 })
229229
expect(spy.calls[4].arguments[0]).toMatch(
230-
/Unexpected keys "bar", "qux".*reducer.*instead: "foo", "baz"/
230+
/Unexpected keys "fred", "grault".*reducer.*instead: "foo", "baz"/
231231
)
232232

233233
reducer(1)
@@ -237,5 +237,26 @@ describe('Utils', () => {
237237

238238
spy.restore()
239239
})
240+
241+
it('only warns for unexpected keys once', () => {
242+
const spy = expect.spyOn(console, 'error')
243+
const foo = (state = { foo: 1 }) => state
244+
const bar = (state = { bar: 2 }) => state
245+
246+
expect(spy.calls.length).toBe(0)
247+
const reducer = combineReducers({ foo, bar })
248+
const state = { foo: 1, bar: 2, qux: 3 }
249+
reducer(state, {})
250+
reducer(state, {})
251+
reducer(state, {})
252+
reducer(state, {})
253+
expect(spy.calls.length).toBe(1)
254+
reducer({ ...state, baz: 5 }, {})
255+
reducer({ ...state, baz: 5 }, {})
256+
reducer({ ...state, baz: 5 }, {})
257+
reducer({ ...state, baz: 5 }, {})
258+
expect(spy.calls.length).toBe(2)
259+
spy.restore()
260+
})
240261
})
241262
})

0 commit comments

Comments
 (0)