Lesson 5 / 25

createSlice, Actions and Immer

Reducers and action creators in one place.

Write mutating code, get immutable updates

createSlice takes a name, an initialState and a reducers object. For each reducer it generates an action creator and an action type such as cart/itemAdded. Reducers run inside Immer, so you may write state.items.push(item): Immer records the changes on a draft and produces a new immutable state. Either mutate the draft or return a new value, not both. extraReducers (a builder callback in Redux Toolkit 2) lets a slice respond to actions defined elsewhere, such as thunks.

A cart slice

cartSlice.ts.

import { createSlice, type PayloadAction } from '@reduxjs/toolkit';

type CartItem = { id: string; qty: number };
type CartState = { items: CartItem[] };

const initialState: CartState = { items: [] };

const cartSlice = createSlice({
  name: 'cart',
  initialState,
  reducers: {
    itemAdded(state, action: PayloadAction<CartItem>) {
      const existing = state.items.find((i) => i.id === action.payload.id);
      if (existing) existing.qty += action.payload.qty; // Immer makes this safe
      else state.items.push(action.payload);
    },
    itemRemoved(state, action: PayloadAction<string>) {
      state.items = state.items.filter((i) => i.id !== action.payload);
    },
    cleared() {
      return initialState; // returning a new value is also allowed
    },
  },
});

export const { itemAdded, itemRemoved, cleared } = cartSlice.actions;
export default cartSlice.reducer;

Editing a photocopy

Immer hands you a photocopy (the draft) to scribble on. When you finish, it produces a clean new original containing your edits, while the old original stays untouched.

Quick check: Why can createSlice reducers write state.items.push(x)?

  • Redux allows mutation since version 2
  • They run inside Immer, which turns draft mutations into an immutable update
  • push is overridden by Redux
  • The state is deep-cloned before every action
Answer

They run inside Immer, which turns draft mutations into an immutable update — Immer tracks changes to a draft.