简体   繁体   English

在ImmutableJS中更新列表中的对象

[英]Updating objects in List in ImmutableJS

I am a little confused by the functionality of ImmutableJS when working with an array of objects. 使用对象数组时,ImmutableJS的功能使我有些困惑。 The following example shows that even though the List x is immutable, I can still modify properties of objects inside the list both with and without using Immutable List's update() function. 下面的示例显示,即使List x是不可变的,无论是否使用Immutable List的update()函数,我仍然可以修改列表中对象的属性。

My question is, why would I use Immutable if I can still modify the contents of my objects? 我的问题是,如果仍然可以修改对象的内容,为什么还要使用不可变? I expected this module to protect me from that. 我希望这个模块可以保护我免受此伤害。 I realize that I will not be able to add or remove entire objects to/from the list, but that doesn't fully protect me from modifying the list, which when working with a list in React state, I do not want to be able to do. 我意识到我将无法在列表中添加或删除整个对象,但这并不能完全保护我免于修改列表,这在使用处于React状态的列表时,我不希望能够去做。

The other interesting thing I noticed is that when I directly modify the name after first performing the update, x.get(0).name and y.get(0).name are both changed. 我注意到的另一件有趣的事情是,当我第一次执行更新后直接修改名称时,x.get(0).name和y.get(0).name都被更改了。 I thought that the resulting list from update() would not contain references to the same objects in the list. 我认为update()生成的列表将不包含对列表中相同对象的引用。

How and why is ImmutableJS really helping me in this case? 在这种情况下,ImmutableJS如何真正地为我提供帮助?

var x = Immutable.List.of({name: 'foo'});
console.log(x.get(0).name);

var y = x.update(0, (element) => {
  element.name = 'bar';
  return element;
});
console.log(x.get(0).name);
console.log(y.get(0).name);

x.get(0).name = 'baz';
console.log(x.get(0).name);
console.log(y.get(0).name);

Output:
foo
bar
bar
baz
baz

https://jsfiddle.net/shotolab/rwh116uw/1/ https://jsfiddle.net/shotolab/rwh116uw/1/

Example of @SpiderPig's suggestion of using Map: @SpiderPig建议使用Map的示例:

var x = Immutable.List.of(new Immutable.Map({name: 'foo'}));
console.log(x.get(0).get('name'));

var y = x.update(0, (element) => {
  return element.set('name', 'bar');
});
console.log(x.get(0).get('name'));
console.log(y.get(0).get('name'));

Output:
foo
foo
bar

While the last example shows what I was trying to accomplish, ultimately I don't know if I will end up using Map or List or even ImmutableJS at all. 虽然最后一个示例显示了我要完成的工作,但最终我还是不知道最终是否会使用Map或List甚至是ImmutableJS。 What I don't like is the alternate APIs (especially for a mapped object). 我不喜欢的是备用API(尤其是映射对象)。 I am afraid that when I hand my project off to another developer, or as others join the team, using these immutable objects and lists correctly will completely fall apart without the proper governance. 恐怕当我将项目移交给其他开发人员时,或者当其他人加入团队时,正确使用这些不可变的对象和列表将完全崩溃,而没有适当的管理。

Maybe this is more of a commentary on React, but if React intends for the state to be immutable, but it's not enforced, it just seems to me like this will end up a mess in a project that is moving quickly with multiple developers. 也许这更多是关于React的评论,但是如果React希望状态是不可变的,但是没有强制执行,在我看来这将最终导致一个项目的混乱,该项目正在与多个开发人员一起快速发展。 I was trying my best not to mutate the state, but forgetting that modifying an object in a list/array is very easy mistake to make. 我尽力不改变状态,但是忘记了修改列表/数组中的对象是很容易犯的错误。

The immutable.js does not provide true immutability in the sense that you could not modify the Objects directly - it just provides API which helps you to maintain the immutable state. 就您无法直接修改Objects而言,immutable.js并未提供真正的不变性-它仅提供了有助于您保持不变状态的API。

The update -function should return completely new version of the indexed object: update -function应该返回索引对象的全新版本:

var y = x.update(0, (element) => {
  return { name : "bar"};
});

But doing something like this is a big no-no: x.get(0).name = 'baz'; 但是做这样的事情是一个很大的x.get(0).name = 'baz';x.get(0).name = 'baz';

Here is a much better explanation of the whole thing than I could ever write: https://github.com/facebook/immutable-js/issues/481 这是整个事情的解释,比我以前写的要好得多: https : //github.com/facebook/immutable-js/issues/481

The point of immutable.js is to allow re-use of objects which are not modified, which consumes less memory and gives a good practical performance. immutable.js的要点是允许重新使用未经修改的对象,这会消耗更少的内存并提供良好的实用性能。

There is also library "Seamless immutable", which freezes the objects, so that they can not be modified, but this comes with some performance penalty under JavaScript: https://github.com/rtfeldman/seamless-immutable 还有一个库“ Seamless immutable”,它冻结了对象,因此无法对其进行修改,但这在JavaScript下会带来一些性能损失: https : //github.com/rtfeldman/seamless-immutable

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM