ImmutableJS - 推入嵌套数组

ImmutableJS - pushing into a nested array

const List = Immutable.List;
const items = [
  { id: 1, subList: [] }, 
  { id: 2, subList: [] }, 
  { id: 3, subList: [] }
];
const newItem = { name: "sublist item" };

let collection = List(items);

collection = collection.updateIn([0, 'subList'], function (items) {
  return items.concat(newItem)
});

https://jsbin.com/midimupire/edit?html,js,console

结果:

Error: invalid keyPath

我想也许我需要将 subList 设置为 List();尝试此操作时出现同样的错误。

使用你得到的对象,更新子数组和return整个对象。

const List = Immutable.List;
const items = [
  { id: 1, subList: [] }, 
  { id: 2, subList: [] }, 
  {id: 3, subList: [] }
];
const newItem = { name: "sublist item" };

let collection = List(items);

collection = collection.update([0], function (obj) {
   obj.subList = obj.subList.concat(newItem)
   return obj;
});

这不起作用,因为您的 Immutable.List 的元素是普通的 JavaScript 对象 (POJO),而不是 Immutable.Map,所以 updateIn 不不知道如何与他们合作。您可以:

  • 使用 Immutable.fromJS instead of Immutable.List as the constructor to convert the entire object graph to Immutable objects. (See JS Bin)
  • 制作对象 Immutable.Maps
  • 使用 update([0]) 而不是 updateIn 来获取 POJO 并对其进行变异(如@Navjot 的回答)。

如果我理解正确的话,你想 return collection 第一个元素为:

{
  id : 1,
  subList: [
    {name: "sublist item"}
  ]
}

为此,我们需要进行一些更改。

  1. 使用Immutable.fromJS将纯JS对象数组深度转换为不可变映射列表

  2. 使用 List.update() 到 return 具有更新值

  3. 的新 List
  4. 使用 Map.updateIn() 到 return 具有更新值的新 LMapist

完整内容如下:

const List = Immutable.List;
const items = [{
    id: 1,
    subList: []
  },
  {
    id: 2,
    subList: []
  },
  {
    id: 3,
    subList: []
  }
];
const newItem = {
  name: "sublist item"
};

let collection = Immutable.fromJS(items);

collection = collection.update(0, item => {
  return item.updateIn(['subList'], subList => {
    return subList.concat(newItem);
  });
});

console.log(collection)
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.js"></script>

结果:

[
  {
    "id": 1,
    "subList": [
      {
        "name": "sublist item"
      }
    ]
  },
  {
    "id": 2,
    "subList": []
  },
  {
    "id": 3,
    "subList": []
  }
]

更新: List.updateIn() 可以使用索引作为键路径,因此您可以将其简化为以下内容:

collection = collection.updateIn([0, 'subList'], subList => {
  return subList.concat(newItem);
});

像这样:

const List = Immutable.List;
const items = [{
    id: 1,
    subList: []
  },
  {
    id: 2,
    subList: []
  },
  {
    id: 3,
    subList: []
  }
];
const newItem = {
  name: "sublist item"
};

let collection = Immutable.fromJS(items);

collection = collection.updateIn([0, 'subList'], subList => {
  return subList.concat(newItem);
});

console.log(collection)
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.js"></script>