【问题标题】:Updating objects in List in ImmutableJS在 ImmutableJS 中更新 List 中的对象
【发布时间】:2023-04-02 16:00:01
【问题描述】:

在处理对象数组时,我对 ImmutableJS 的功能有点困惑。下面的例子表明,即使 List x 是不可变的,我仍然可以修改列表内对象的属性,无论是否使用不可变列表的 update() 函数。

我的问题是,如果我仍然可以修改对象的内容,为什么还要使用 Immutable?我希望这个模块能保护我免受这种影响。我意识到我将无法在列表中添加或删除整个对象,但这并不能完全保护我免于修改列表,当使用处于 React 状态的列表时,我不希望能够去做。

我注意到的另一个有趣的事情是,当我在第一次执行更新后直接修改名称时,x.get(0).name 和 y.get(0).name 都被更改了。我认为 update() 的结果列表不会包含对列表中相同对象的引用。

在这种情况下,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/

@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

虽然最后一个示例显示了我想要完成的工作,但最终我不知道我最终是否会使用 Map 或 List 甚至 ImmutableJS。我不喜欢的是备用 API(尤其是映射对象)。我担心当我将我的项目交给另一个开发人员时,或者当其他人加入团队时,如果没有适当的治理,正确使用这些不可变对象和列表会完全崩溃。

也许这更像是对 React 的评论,但如果 R​​eact 打算让状态是不可变的,但它没有强制执行,那么在我看来,这最终会在一个快速发展的项目中变得一团糟开发商。我尽力不改变状态,但忘记修改列表/数组中的对象是很容易犯的错误。

【问题讨论】:

  • 只有列表本身是不可变的。它里面的物体不是。您可以将不可变元素放入您的列表中,例如使用 Immutable.Map 而不是普通的 JS 对象。
  • 我添加了一个您的建议示例,它结合了 Map 和 List 的使用。这最终实现了我所追求的,但副作用是需要不同的 API 来修改 Mapped 对象,而不仅仅是一个普通的 JS 对象。

标签: javascript reactjs immutable.js


【解决方案1】:

在您无法直接修改对象的意义上,immutable.js 不提供真正的不变性 - 它只是提供帮助您保持不可变状态的 API。

更新函数应该返回索引对象的全新版本:

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

但是这样做是一个很大的禁忌:x.get(0).name = 'baz';

这里有一个比我写的更好的解释: https://github.com/facebook/immutable-js/issues/481

immutable.js的重点是允许重复使用未修改的对象,这样占用内存少,实用性能好。

还有一个库“Seamless immutable”,它冻结对象,使它们不能被修改,但这在 JavaScript 下会带来一些性能损失:https://github.com/rtfeldman/seamless-immutable

【讨论】:

  • 感谢您提供指向问题 481 的链接。您的回答证实了至少我遇到的行为是预期的行为。
猜你喜欢
  • 1970-01-01
  • 2018-01-27
  • 2019-02-03
  • 2011-11-03
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 2012-03-21
相关资源
最近更新 更多