Answer
No – if a legacy reducer and an RTK slice both try to update the same part of the state tree, the store’s state transitions become unpredictable. The reducer that runs last will overwrite the changes made by the first, and any Immer‑based mutative logic in the slice will not protect against concurrent writes from the legacy reducer.
Confirmed facts
- Redux Toolkit’s
createSlice produces a standard Redux reducer that can be combined with any other reducer via combineReducers.
- Each key in the state object is handled by exactly one reducer; duplicate keys cause the later reducer to replace the earlier one.
- Immer’s mutative syntax only works inside the reducer returned by
createSlice (or createReducer). Legacy reducers must return new state objects themselves.
Likely explanation
When both reducers receive the same action, they each receive the same slice of state (the value under their shared key). The legacy reducer may return a new object, while the slice reducer (using Immer) also returns a new object. Because Redux calls the reducers sequentially, the final state is whatever the last reducer returns, causing the first reducer’s updates to be lost. This breaks predictability and can lead to missing data or hard‑to‑trace bugs.
Recommended migration strategy
- Identify overlapping state keys – locate the slice of state that both the legacy reducer and the RTK slice attempt to modify.
- Assign ownership to one reducer – decide which pattern will own that piece of state during the migration phase.
- Make the non‑owner a no‑op for relevant actions – if the legacy reducer is being replaced, have it return
state unchanged for the actions now handled by the slice; if the slice is being added, use extraReducers to listen to legacy actions without modifying state.
- Migrate the logic – move the case logic from the legacy reducer into the slice’s
reducers map, rewriting it with Immer’s mutative syntax.
- Combine and verify – replace the legacy reducer file with the slice’s reducer, run the app, and confirm behavior with Redux DevTools or unit tests.
If the legacy reducer relies on non‑string action types (e.g., Symbols) or custom middleware that mutates state, the above steps need adjustment. Please confirm whether the legacy reducer uses any non‑string action types or state‑mutating middleware so we can tailor the migration approach.