Skip to content

Instantly share code, notes, and snippets.

@davipviana
Last active June 19, 2020 22:16
Show Gist options
  • Save davipviana/f8e77187aa8dc6f821dfe072374ec439 to your computer and use it in GitHub Desktop.
Save davipviana/f8e77187aa8dc6f821dfe072374ec439 to your computer and use it in GitHub Desktop.
React Immutable update patterns

Immutable Update Patterns

Table of Contents

Updating Nested Objects

The key to updating nested data is that every level of nesting must be copied and updated appropriately. This is often a difficult concept for those learning Redux, and there are some specific problems that frequently occur when trying to update nested objects. These lead to accidental direct mutation, and should be avoided.

Common Mistake #1: New variables that point to the same objects

function updateNestedState(state, action) {
    let nestedState = state.nestedState;
    // ERROR: this directly modifies the existing object reference - don't do this!
    nestedState.nestedField = action.data;
    
    return {
        ...state,
        nestedState
    };
}

Common Mistake #2: Only making a shallow copy of one level

function updateNestedState(state, action) {
    // Problem: this only does a shallow copy!
    let newState = {...state};
    
    // ERROR: nestedState is still the same object!
    newState.nestedState.nestedField = action.data;
    
    return newState;
}

Correct Approach: Copying All Levels of Nested Data

function updateVeryNestedField(state, action) {
    return {
        ...state,
        first : {
            ...state.first,
            second : {
                ...state.first.second,
                [action.someId] : {
                    ...state.first.second[action.someId],
                    fourth : action.someValue
                }
            }
        }
    }
}

Inserting and Removing Items in Arrays

function insertItem(array, action) {
    return [
        ...array.slice(0, action.index),
        action.item,
        ...array.slice(action.index)
    ]
}
    
function removeItem(array, action) {
    return [
        ...array.slice(0, action.index),
        ...array.slice(action.index + 1)
    ];
}

Updating an Item in an Array

function updateObjectInArray(array, action) {
    return array.map( (item, index) => {
        if(index !== action.index) {
            // This isn't the item we care about - keep it as-is
            return item;
        }
    
        // Otherwise, this is the one we want - return an updated value
        return {
            ...item,
            ...action.item
        };    
    });
}

Useful function

const updateObject = (oldObject, updatedValues) => {
    return {
        ...oldObject,
        ...updatedValues
    };
}

Reference

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment