diff --git a/src/combineReducers.js b/src/combineReducers.js index 8dedc64e38..2ff760bd2a 100644 --- a/src/combineReducers.js +++ b/src/combineReducers.js @@ -44,6 +44,8 @@ function getUnexpectedStateShapeWarningMessage(inputState, reducers, action, une unexpectedKeyCache[key] = true }) + if (action && action.type === ActionTypes.REPLACE) return + if (unexpectedKeys.length > 0) { return ( `Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` + diff --git a/src/createStore.js b/src/createStore.js index 94928acd36..8b340274ea 100644 --- a/src/createStore.js +++ b/src/createStore.js @@ -213,7 +213,7 @@ export default function createStore(reducer, preloadedState, enhancer) { } currentReducer = nextReducer - dispatch({ type: ActionTypes.INIT }) + dispatch({ type: ActionTypes.REPLACE }) } /** diff --git a/src/utils/actionTypes.js b/src/utils/actionTypes.js index 82c3ffedbe..3e087d106c 100644 --- a/src/utils/actionTypes.js +++ b/src/utils/actionTypes.js @@ -4,8 +4,9 @@ * If the current state is undefined, you must return the initial state. * Do not reference these action types directly in your code. */ -var ActionTypes = { - INIT: '@@redux/INIT' +const ActionTypes = { + INIT: '@@redux/INIT' + Math.random().toString(36).substring(7).split('').join('.'), + REPLACE: '@@redux/REPLACE' + Math.random().toString(36).substring(7).split('').join('.') } export default ActionTypes diff --git a/test/createStore.spec.js b/test/createStore.spec.js index 62d209fc79..9583d8bc61 100644 --- a/test/createStore.spec.js +++ b/test/createStore.spec.js @@ -767,4 +767,30 @@ describe('createStore', () => { expect(results).toEqual([ { foo: 0, bar: 0, fromRx: true }, { foo: 1, bar: 0, fromRx: true } ]) }) }) + + it('does not log an error if parts of the current state will be ignored by a nextReducer using combineReducers', () => { + const originalConsoleError = console.error + console.error = jest.fn() + + const store = createStore( + combineReducers({ + x: (s=0, a) => s, + y: combineReducers({ + z: (s=0, a) => s, + w: (s=0, a) => s, + }), + }) + ) + + store.replaceReducer( + combineReducers({ + y: combineReducers({ + z: (s=0, a) => s, + }), + }) + ) + + expect(console.error.mock.calls.length).toBe(0) + console.error = originalConsoleError + }) })