Blog>
Snippets

Using Immer for Nested State Updates

Demonstrate how to update nested objects in a Redux state using createReducer and Immer, focusing on changing a deeply nested value without mutating the original state.
import { createAction, createReducer } from '@reduxjs/toolkit';
import produce from 'immer';

// Define an action creator
const updateNestedValue = createAction('update/nestedValue');

// Initial state for the reducer
const initialState = {
  levelOne: {
    levelTwo: {
      levelThree: {
        myValue: 0
      }
    }
  }
};

// Create reducer using createReducer and Immer
const nestedValueReducer = createReducer(initialState, {
  [updateNestedValue]: (state, action) => {
    // Immer allows you to write code that 'mutates' the draft state
    // This mutation will result in a new immutable state object
    state.levelOne.levelTwo.levelThree.myValue = action.payload;
  }
});
This code snippet demonstrates the use of Redux Toolkit's createReducer function alongside Immer to produce a reducer that updates a deeply nested value in the state. An action called 'updateNestedValue' is created first. The initialState object has three levels of nested objects, ending with 'myValue' as the target property to update. The 'nestedValueReducer' is then defined with a mapping from the 'updateNestedValue' action to a reducer function that takes the current state and an action. Inside this reducer function, Immer's proxy-based draft state allows us to directly 'mutate' the nested 'myValue' property, which returns a new, immutably updated state containing the changes.