Reputation: 450
What is the reason behind this code working
return state.update(action.id, function(item) {
return {id: item.id, title: item.title, duration: item.duration - 1 };
});
and this one that does not work?
return state.update(action.id, function(item) {
item.duration = item.duration - 1;
return item;
});
What is the main difference?
Upvotes: 0
Views: 128
Reputation: 10153
ImmitableJS's List is not "deeply immutable". item
is a reference. For you to end up with a new List reference after this operation (and your React components to know something changed) the List references themselves need to change, not just data inside the objects referenced by item
s.
The reason your first example works is that you are dropping a reference from the List and adding a new one, meaning you get a new List (different reference).
The second example does not alter the references themselves, just the data in the objects, thus you won't get a new List reference.
You could initialize this List by doing a Immutable.fromJS()
to get your initial List instance. This one is going to create a "deeply immutable" List that will behave like you expect it to in your second example.
Try this (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);
With this output:
Object {id: "x"} Object {id: "x"} true true
Object {id: "x"} Object {id: "x"} false
false
For React to know your list changed the comparison has to be false
.
Upvotes: 2