Skip to content

Instantly share code, notes, and snippets.

@gorangajic
Last active April 11, 2024 08:32
Show Gist options
  • Save gorangajic/e902c2ee994260b3348d to your computer and use it in GitHub Desktop.
Save gorangajic/e902c2ee994260b3348d to your computer and use it in GitHub Desktop.
es6 spread immutable cheatsheet

update object

var state = {
    id: 1,
    points: 100,
    name: "Goran"
};

var newState = {
    ...state,
    points: 120
}

console.log(newState);
/* 
  {
    id: 1,
    points: 120,
    name: "Goran"
  }
*/

update array

var state = [1,1,1,1];

// state[2]++ // [1,1,2,1]
var index = 2;
var newState = [
    ...state.slice(0, index),
    state[index] + 1,
    ...state.slice(index + 1)
];
console.log(newState);
/*
  [1,1,2,1]
*/

filter object with Array.prototype.reduce

const items = {
  1: {
    id: 1,
    name: "Goran"
  }, 
  2: {
    id: 2,
    name: "Petar"
  }
};

const filterId = 1;

const filteredItems = Object.keys(items).reduce( (accumulator, key) => (
   items[key].id === filterId ? accumulator : {
       ...accumulator,
       [key]: items[key]
   }                                        
), {});

console.log(filteredItems);
/*
  {
    2: {
      id: 2,
      name: "Petar"
    }
  }
  }
*/

update array with objects using Array.prototype.slice

var state = [
  {name: "Goran"},
  {name: "Peter"}
]

// you can use es6 Array.prototype.findIndex to find index of the object
// let index = state.findIndex(({name}) => name === "Peter");
var index = 1;
var field = 'name';
var value = 'Zika';

var newState = [
  ...state.slice(0, index),
  {
    ...state[index],
    [field]: value
  },
  ...state.slice(index + 1)
];

console.log(newState);
/*
  [
    {name: "Goran"},
    {name: "Zika"}
  ]
*/

normalize array and merge with id=>val object

var items = {1: {name: "Airplane", id: 1}, 2: {name: "Spaceship", id:2}};
var receivedItems = [{id: 3, name: "Quadrocopter"}, {id: 4, name: "Helicopter"}];
var newState = {
    ...items,
    ...receivedItems.reduce((obj, item) => ({
        ...obj,
        [item.id]: item
    }), {})
}
console.log(newState);
/*
{
    1: {name: "Airplane", id: 1}, 
    2: {name: "Spaceship", id: 2},
    3: {name: "Quadrocopter", id: 3},
    4: {name: "Helicopter", id: 4}
}
*/
@timbuckley
Copy link

timbuckley commented Dec 29, 2016

@gorangajic Typo in the first example "Update object":

var newState = {
    ..state, // <- should be three dots.
    points: 120
}

@gorangajic
Copy link
Author

@timbuckley updated, thanks

@Jonarod
Copy link

Jonarod commented Mar 7, 2018

@gorangajic I may not undertsand this gist, but how come newState is ever immutable ?
Correct me if I am wrong, but doesn't "immutable" means "not mutable" ? If so, then you should try this (based on your examples):

var state = [
  {name: "Goran"},
  {name: "Peter"}
]

var newState = [
  ...state.slice(0)
];

state[0].name = "Mutating state, not newState"

console.log(newState);
/*
  [
    {name: "Mutating state, not newState"},
    {name: "Zika"}
  ]
*/

and print your newState to console: you should see that it has mutated while updating supposedly unrelated state variable :/
Did I miss something ?

@envynoiz
Copy link

envynoiz commented Jun 24, 2018

Hi @Jonarod! that happens because you are using objects, so the reference to the objects inside the newState array is the same located in state array.

So when you did

var newState = [
  ...state.slice(0)
]

You are only changing the reference of the array but the reference in objects still remaining the same in both.

That is the reason why in the above example he needs to do this:

{
    ...state[index],
    [field]: value
}

You can see the spread operator in state[index] in order to get a shallow copy of the current object in the state array giving with that a new reference in the newState array.

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