在不丢失引用的情况下更新 ImmutableJS OrderedMap 上的记录
Posted
技术标签:
【中文标题】在不丢失引用的情况下更新 ImmutableJS OrderedMap 上的记录【英文标题】:Updating Records on ImmutableJS OrderedMap without losing reference 【发布时间】:2015-07-23 20:16:58 【问题描述】:我正在使用 ImmutableJS OrderedMap 将 ImmutableJS 记录存储在 React 应用程序中。我想知道在不丢失对记录的引用的情况下,处理共享相同值的更新的惯用方法是什么。例如,给定以下代码,如果要在键 1 处更新的记录与键 1 处的当前记录具有相同的值,那么在键 1 处更新 fooBars
对象的正确方法是什么。
import Immutable from 'immutable';
let fooBars = Immutable.OrderedMap();
let FooBar = Immutable.Record(id: undefined);
let fooBar1 = new FooBar(id: 1);
let fooBar2 = new FooBar(id: 1);
fooBars = fooBars.set(fooBar1.id, fooBar1);
// this will lose reference to fooBar1 despite the values not changing
// and cause the DOM to reconcile forcing a re-render of the component
fooBars = fooBars.update(fooBar2.id, fooBar2);
【问题讨论】:
【参考方案1】:您正在以正确的方式更新它。
要记住的是,对不可变对象的每个突变操作都会产生一个全新的对象。
所以,从你的例子中:
fooBars = fooBars.set(fooBar1.id, fooBar1);
fooBars2 = fooBars.update(fooBar2.id, fooBar2);
您现在有 2 个对象,fooBars1
和 fooBars2
。它们是完全不同的 javascript 对象,所以 fooBars1 !== fooBars2
。但是,它们是相同的不可变对象,所以Immutable.is(fooBars1, fooBars2) === true
。
因此,为了防止发生重新渲染,您必须利用任何组件 shouldComponentUpdate
方法来检查旧道具或状态是否与新道具或状态相同。
shouldComponentUpdate(nextProps)
return !Immutable.is(this.props.fooBars, next.props.fooBars);
【讨论】:
这是 1 个解决方案,但这会使 shouldComponentUpdate 减慢大约 3 倍。 shouldComponentUpdate 方法运行很多次,这会对性能造成很大影响。 如果您不想进行该检查,则不要换出基础记录。因为 fooBar1 !== fooBar2,将键 1 的值从 fooBar1 更改为 fooBarN 将永远不会产生相同的 Immutable。如果不是换出记录,而是更新它们,您将取回原始对象,您可以只使用 === 或 pureRenderMixin。 fooBars.updateIn([1,"id"], function() return 1) === fooBars以上是关于在不丢失引用的情况下更新 ImmutableJS OrderedMap 上的记录的主要内容,如果未能解决你的问题,请参考以下文章
如何在不丢失 docker 数据的情况下更新 prometheus 配置文件