Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the shortest way to modify immutable objects using spread and destructuring operators

I'm looking for a pure function, to modify my immutable state object. The original state given as parameter must stay untouched. This is especially useful when working with frameworks like Redux and makes working with immutable object in javascript much easier. Especially since working with the object spread operator using Babel is already possible.

I did not found anything better than first copy the object, and than assign/delete the property I want like this:

function updateState(state, item) {   newState = {...state};   newState[item.id] = item;   return newState; }  function deleteProperty(state, id) {     var newState = {...state};     delete newState[id];     return newState; } 

I feel like it could be shorter

like image 611
Tarion Avatar asked Apr 11 '16 15:04

Tarion


People also ask

What is the difference between Destructuring and spread operator?

While spread syntax helps expand or spread elements and properties, the rest parameter helps collect them together. In the case of objects, the rest parameter is mostly used with destructuring syntax to consolidate the remaining properties in a new object you're working with.

Is spread operator immutable?

The original array remains intact if you copy the array with the spread operator and append it to the new one. Doing so supports immutability and prevents unforeseen side-effects.

Can you use the spread operator on an object?

Use the object spread operator to clone an object or merge objects into one. Cloning is always shallow. When merging objects, the spread operator defines new properties while the Object.


2 Answers

Actions on state, where state is considered immutable.

Adding or Updating the value of a property:

// ES6: function updateState(state, item) {     return Object.assign({}, state, {[item.id]: item}); }  // With Object Spread: function updateState(state, item) {   return {      ...state,      [item.id]: item   }; } 

Deleting a property

// ES6: function deleteProperty(state, id) {     var newState = Object.assign({}, state);     delete newState[id];     return newState;  }  // With Object Spread: function deleteProperty(state, id) {     let  {[id]: deleted, ...newState} = state;     return newState; }  // Or even shorter as helper function: function deleteProperty({[id]: deleted, ...newState}, id) {     return newState; }  // Or inline: function deleteProperty(state, id) {     return (({[id]: deleted, ...newState}) => newState)(state); } 
like image 58
Tarion Avatar answered Sep 23 '22 04:09

Tarion


An ES6 solution, that has a bit more support is Object.assign:

const updateState = (state, item) => Object.assign({}, state, { [item.id]: item }); 
like image 43
Ori Drori Avatar answered Sep 22 '22 04:09

Ori Drori