Skip to content

Commit

Permalink
REPLACE action for replaceReducers (reduxjs#2673)
Browse files Browse the repository at this point in the history
* Add an explicit private action type for replacing reducers

* Make this a const while we're at it...

* Triple equals for lint

* Add a random string to the "private" actions.
  • Loading branch information
timdorr authored and seantcoyote committed Jan 14, 2018
1 parent 9d78dcb commit 87349e9
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/combineReducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'} ` +
Expand Down
2 changes: 1 addition & 1 deletion src/createStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export default function createStore(reducer, preloadedState, enhancer) {
}

currentReducer = nextReducer
dispatch({ type: ActionTypes.INIT })
dispatch({ type: ActionTypes.REPLACE })
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/utils/actionTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
26 changes: 26 additions & 0 deletions test/createStore.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
})

0 comments on commit 87349e9

Please sign in to comment.