diff --git a/src/createStore.js b/src/createStore.js index bfe9d69123..36aaf21e36 100644 --- a/src/createStore.js +++ b/src/createStore.js @@ -196,6 +196,17 @@ export default function createStore(reducer, preloadedState, enhancer) { throw new Error('Expected the nextReducer to be a function.') } + const reducerShape = nextReducer({}, {}) + + if (typeof currentState === 'object' && Array.isArray(currentState) === false) { + currentState = Object.keys(currentState).reduce((targetShape, key) => { + if (key in reducerShape) { + targetShape[key] = currentState[key] + } + return targetShape + }, {}) + } + currentReducer = nextReducer dispatch({ type: ActionTypes.INIT }) } diff --git a/test/createStore.spec.js b/test/createStore.spec.js index 90e60b73b2..a4e25b9ccd 100644 --- a/test/createStore.spec.js +++ b/test/createStore.spec.js @@ -601,6 +601,21 @@ describe('createStore', () => { ).not.toThrow() }) + it('does not warn if replaceReducer changes reducer shape', () => { + const preSpy = console.error + const spy = jest.fn() + console.error = spy + + const store = createStore(combineReducers({ foo: reducers.todos })) + expect(spy.mock.calls.length).toBe(0) + + store.replaceReducer(combineReducers({ bar: reducers.todos })) + expect(spy.mock.calls.length).toBe(0) + + spy.mockClear() + console.error = preSpy + }) + it('throws if listener is not a function', () => { const store = createStore(reducers.todos)