使用扩展运算符和析构函数运算符修改不可变对象的最短方法是什么

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

本文关键字:运算符 对象 方法 是什么 修改 扩展 析构函数 不可变      更新时间:2024-04-20

我正在寻找一个纯函数来修改我的不可变状态对象。作为参数给定的原始状态必须保持不变。这在处理像Redux这样的框架时尤其有用,并使处理javascript中的不可变对象变得更加容易。特别是因为使用Babel处理对象扩散操作符已经是可能的。

我没有发现比第一次复制对象和分配/删除我想要的属性更好的东西:

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

我觉得可能更短

对状态的操作,其中状态被认为是不可变的。

添加或更新属性值

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

删除属性

// 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);
}

一个支持Object.assign:的ES6解决方案

const updateState = (state, item) => Object.assign({}, state, { [item.id]: item });

在映射函数中

要在映射函数中执行此过程(在每个对象上删除一个属性并添加一个新属性),请给定一个对象数组-

const myArrayOfObjects = [
    {id: 1, keyToDelete: 'nonsense'},
    {id: 2, keyToDelete: 'rubbish'}
];

删除属性keyToDelete,并添加值为"someVar"的新密钥newKey

myArrayOfObjects.map(({ keyToDelete, ...item}) => { ...item, newKey:'someVar'});

将阵列更新为

[
    {id: 1, newKey:'someVar'},
    {id: 2, newKey:'someVar'}
]

有关删除方法的更多信息,请参阅这篇伟大的文章。

您可以使用一些库来做同样的事情,而不是编写难以阅读的样板代码(如上所述:(({[id]: deleted, ...state}) => state)(state)):

  • https://github.com/cah4a/immutable-modify
  • https://github.com/kolodny/immutability-helper
  • https://github.com/M6Web/immutable-set
  • https://github.com/bormind/immutable-setter

例如:

import {remove} from 'immutable-modify'
function updateState(state, item) {
   return remove(state, item.id)
}

它还支持任何嵌套更新:

import {set} from 'immutable-modify'
function updateState(state, item) {
   return set(state, 'user.products', (products) => ({
      ...products,
      items: products.items.concat(item),
      lastUpdate: Date.now()
   }))
}

尝试:

const { id, ...noId } = state;

测试:

console.log(noId);

从数组中删除项,只需使用filter;)

CASE 'REMOVE_ITEM_SUCCESS':
      let items = state.items.filter(element => element._id !== action.id);
      return {
            ...state, 
            items
      }