Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save kvasss/b84b4074e92a4961d157f3541a6885a0 to your computer and use it in GitHub Desktop.

Select an option

Save kvasss/b84b4074e92a4961d157f3541a6885a0 to your computer and use it in GitHub Desktop.
React / JS - How to replace an array item without mutating @see: https://stackoverflow.com/a/49502115

ES6 Method

handleChange: function (e) {
    // 1. Make a shallow copy of the items
    let items = [...this.state.items];
    // 2. Make a shallow copy of the item you want to mutate
    let item = {...items[1]};
    // 3. Replace the property you're intested in
    item.name = 'newName';
    // 4. Put it back into our array. N.B. we *are* mutating the array here, but that's why we made a copy first
    items[1] = item;
    // 5. Set the state to our new copy
    this.setState({items});
},

You can combine steps 2 and 3 if you want:

let item = {
    ...items[1],
    name: 'newName'
}

Or you can do the whole thing in one line:

this.setState(({items}) => ({
    items: [
        ...items.slice(0,1),
        {
            ...items[1],
            name: 'newName',
        },
        ...items.slice(2)
    ]
}));

React Immutability Method

React offers a library solution for this: https://reactjs.org/docs/update.html

import update from 'react-addons-update';

const newData = update(myData, {
  x: {y: {z: {$set: 7}}},
  a: {b: {$push: [9]}}
});

Available Commands

  • {$push: array} push() all the items in array on the target.
  • {$unshift: array} unshift() all the items in array on the target.
  • {$splice: array of arrays} for each item in arrays call splice() on the target with the parameters provided by the item.
  • {$set: any} replace the target entirely.
  • {$merge: object} merge the keys of object with the target.
  • {$apply: function} passes in the current value to the function and updates it with the new returned value.

Examples

Simple push

const initialArray = [1, 2, 3]; const newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]

initialArray is still [1, 2, 3].

Nested collections

const collection = [1, 2, {a: [12, 17, 15]}]; const newCollection = update(collection, {2: {a: {$splice: [[1, 1, 13, 14]]}}}); // => [1, 2, {a: [12, 13, 14, 15]}]

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