Skip to content

Instantly share code, notes, and snippets.

@rszczypka
Last active May 23, 2017 17:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rszczypka/490133e64b1f0d9d24b4756b854308fc to your computer and use it in GitHub Desktop.
Save rszczypka/490133e64b1f0d9d24b4756b854308fc to your computer and use it in GitHub Desktop.
Immutable ways to work with Redux

Redux

  • Single, immutable state tree
  • State flows down
  • Events flow up
  • No more managing parts of state in separate controllers and services

This is transcript from https://egghead.io/lessons/javascript-redux-avoiding-array-mutations-with-concat-slice-and-spread#/tab-transcript

const addCounter = (list) => {
  return list.concat([0]);
};

Now the tests pass without mutations, and I can also use the new ES6 array spread operator to write the same code in a more concise way.

const addCounter = (list) => {
  return [...list, 0];
};

Usually, to delete an item from the array, I would use the splice method. However, splice is a mutating method, so you can't use it in Redux.

const removeCounter = (list, index) => {
  list.splice(index, 1);
  return list;
};

I'm using a method called slice here, and it doesn't have anything to do with splice. It is not mutating, and it gives me a part of the array from some beginning to some end index.

const removeCounter = (list, index) => {
  return [
    ...list.slice(0, index),
    ...list.slice(index + 1)
  ];
};

What Im doing is that Im taking the parts before the index I want to skip and after the index I want to skip, and I concatenate them to get a new array.

Finally, instead of writing it as a method chain with concat calls, I can use the ES6 array spread operator to write it more concisely.

const incrementCounter = (list, index) => {
  return [
    ...list.slice(0,index),
    list[index] + 1,
    ...list.slice(index + 1)
  ];
};

Finally, with the ES6 spread operator, we can spread over the left part of the array, specify the new item, and then spread over the right part of the original array, and this looks much nicer.

// INSERT ITEM
return [...state, action.payload];
// or
return state.concat(action.payload);
// UPDATE ITEM
return state.map(item => {
return item[comparator] === action.payload[comparator] ? Object.assign({}, item, action.payload) : item;
}
// DELETE ITEM
return state.filter(item => {
return item[comparator] !== action.payload[comparator];
});
return arr.slice(0,index).concat(arr.slice(index+1))
// COPY AN ARRAY
let arr = ['a', 'b', 'c']
let newArr = [ ...arr ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment