Blog>
Snippets

Simplifying Deep Updates with Immer’s produce

Showcase using Immer’s produce function to handle a complex state update that involves nested objects and arrays, highlighting the improved readability and maintainability.
import produce from 'immer';

const initialState = {
    user: {
        name: 'Alice',
        age: 30,
        address: {
            street: '123 Main St',
            city: 'Anytown'
        }
    },
    tasks: [
        { id: 1, text: 'Buy milk', done: false },
        { id: 2, text: 'Write report', done: true }
    ]
};

const nextState = produce(initialState, draft => {
    // Updating a deeply nested value
    draft.user.address.city = 'New City';
    
    // Adding to a nested array
    draft.tasks.push({ id: 3, text: 'Call Bob', done: false });
    
    // Updating an item inside a nested array
    const taskToComplete = draft.tasks.find(task => task.id === 1);
    if(taskToComplete) {
        taskToComplete.done = true;
    }
});

console.log(nextState);
This example uses Immer's produce function to immutably update a complex state object. The 'initialState' represents some user data and a list of tasks. Within the produce function's 'draft', we update the city of the user's address, push a new task into the tasks array, and find a specific task to mark it as done. The original 'initialState' is not mutated, and 'nextState' is a new, updated, immutable state.