从嵌套对象中删除数据而不发生变异

时间:2016-02-11 14:42:33

标签: javascript immutability redux mutation

是否有任何优雅的方法从数组中删除对象是数组的一部分? 我一直在使用React和Redux一段时间,但每次我必须删除或插入数据而不改变状态时会卡住几个小时。

reducer是一个数组,包含具有ID的对象和另一个包含对象的数组,如下所示:

[
 { id:123,
   items:[
           { id: abc,
             name: albert
           }, 
           ... 
         ]
 }, 
 ... 
]

我收到两个ID,需要删除ID为abc的项目。

6 个答案:

答案 0 :(得分:35)

通过id:

从数组中删除项目
return state.filter(item => item.id !== action.id)

通过id:

从对象中删除键
let copy = Object.assign({}, state) // assuming you use Object.assign() polyfill!
delete copy[action.id] // shallowly mutating a shallow copy is fine
return copy

(奖金)与object spread operator proposal相同:

let { [action.id]: deletedItem, ...rest } = state
return rest

答案 1 :(得分:2)

const remove = (state, bucketId, personId) => state.map(
  bucket => bucket.id === bucketId
    ? { ...bucket, items: bucket.items.filter(person => person.id !== personId) }
    : bucket,
);

用法:

const state = [
  {
    id: 123,
    items: [
      {
        id: 'abc',
        name: 'Kinna',
      },
      {
        id: 'def',
        name: 'Meggy',
      },
    ],
  },
  {
    id: 456,
    items: [
      {
        id: 'ghi',
        name: 'Ade',
      },
      {
        id: 'jkl',
        name: 'Tades',
      },
    ],
  },
];

console.log(remove(state, 123, 'abc'));

答案 2 :(得分:0)

您可以使用Underscore's reject。它完全符合您的要求。

答案 3 :(得分:0)

If you decide for plain Javascript, the most elegant way I can think of is to use -agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n to reduce the state:

Array.prototype.reduce

答案 4 :(得分:0)

您也可以使用lodash's omit method

请注意,导入lodash会大大增加构建大小。通过仅导入特定方法来稍微检查一下: import omit from 'lodash/omit';

如果可能,我建议使用Dan's answer中描述的对象扩展运算符。

答案 5 :(得分:0)

我以这种方式解决了我的问题

if(action.type === "REMOVE_FROM_PLAYLIST"){
        let copy = Object.assign({}, state) 
        delete copy.playlist[action.index].songs[action.indexSongs];

        return copy;
    }

希望它可以帮助其他任何人。