Blog>
Snippets

Correcting State Mutation Errors in ExtraReducers

Present an example of a common mistake where direct state mutation is performed in extraReducers, followed by the corrected approach using immutable update patterns or functions.
const todoSlice = createSlice({
    name: 'todos',
    initialState: [],
    reducers: {},
    extraReducers: {
        [todoAdded.type]: (state, action) => {
            // Mistake: direct mutation of state
            state.push(action.payload);
        }
    }
});
The code incorrectly mutates the state directly by using push inside extraReducers.
const todoSlice = createSlice({
    name: 'todos',
    initialState: [],
    reducers: {},
    extraReducers: {
        [todoAdded.type]: (state, action) => {
            // Correct approach: using Immer to handle the immutable update
            state.push(action.payload);
        }
    }
});
The corrected code still uses push, but it's allowed and correctly managed by Immer within createSlice which creates an immutable update under the hood.
const todoSlice = createSlice({
    name: 'todos',
    initialState: [],
    reducers: {},
    extraReducers: (builder) => {
        builder.addCase(todoAdded.type, (state, action) => {
            // Correct use of Immer with builder.addCase
            state.push(action.payload);
        });
    }
});
Alternatively, you can use the 'builder callback' notation, which also uses Immer to manage immutability.