ImmutableJS更新列表

时间:2016-04-22 12:42:35

标签: reactjs immutable.js

此代码工作的原因是什么

  return state.update(action.id, function(item) {
    return {id: item.id, title: item.title, duration: item.duration - 1 };
  });

这个不起作用?

  return state.update(action.id, function(item) {
    item.duration = item.duration - 1;
    return item;
  });

主要区别是什么?

1 个答案:

答案 0 :(得分:2)

ImmitableJS的列表不是"非常不可变的"。 item是一个参考。为了让您在此操作之后最终得到一个新的List引用(以及您的React组件知道更改的内容),List引用本身需要更改,而不仅仅是item引用的对象内的数据。

你的第一个例子工作的原因是你从List中删除一个引用并添加一个新引用,这意味着你得到一个新的List(不同的引用)。

第二个例子不会改变引用本身,只改变对象中的数据,因此你不会获得新的List引用。

您可以通过执行Immutable.fromJS()初始化此列表来获取初始List实例。这个将创造一个不可改变的"列表将在您的第二个示例中表现得像您期望的那样。

试试这个(here's the fiddle for it):

var list = Immutable.List([ {id: 1}, {id: 2}, {id: 3} ]);

var deepList = Immutable.fromJS([ {id: 1}, {id: 2}, {id: 3} ]);

var mutatedList1 = list.update(0, function(item) {
    item.id = 'x';
    return item;
});

var mutatedList2 = list.update(0, function(item) {
    return {id: 'x' };
});

var mutatedList3 = deepList.update(0, function(item) {
    return {id: 'x' };
});


console.log(list.get(0), mutatedList1.get(0), list.get(0) === mutatedList1.get(0), list === mutatedList1);
console.log(list.get(0), mutatedList2.get(0), list === mutatedList2);
console.log(deepList === mutatedList3);

使用此输出:

Object {id: "x"} Object {id: "x"} true true
Object {id: "x"} Object {id: "x"} false
false

如果React知道您的列表已更改,则比较必须为false