在不丢失引用的情况下更新 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 个对象,fooBars1fooBars2。它们是完全不同的 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 配置文件

在不丢失单元格焦点的情况下刷新 WPF DataGrid

如何在不丢失现有值的情况下编辑复选框

如何在不丢失原始参与者的情况下将现有呼叫升级到会议?

如何在不丢失“this”上下文的情况下从 React 组件中写入 apollo 缓存

在不删除数据的情况下更新数据库架构?