在不丢失引用的情况下更新ImmutableJS OrderedMap上的记录

evk*_*ine 1 javascript reactjs reactjs-flux immutable.js

我正在使用ImmutableJS OrderedMap在React应用程序中存储ImmutableJS Records.我想知道处理共享相同值的更新的惯用方法是什么,而不会丢失对Record的引用.例如,给定以下代码,如果要fooBars在键1处更新的记录与键1处的当前记录保持相同的确切值,那么在键1处更新对象的正确方法是什么.

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);
Run Code Online (Sandbox Code Playgroud)

Cro*_*rob 5

您正在以正确的方式更新它.

要记住的是,对不可变的每个变异操作都会产生一个全新的对象.

所以,从你的例子来看:

fooBars = fooBars.set(fooBar1.id, fooBar1); 
fooBars2 = fooBars.update(fooBar2.id, fooBar2);
Run Code Online (Sandbox Code Playgroud)

你现在有2个对象,fooBars1fooBars2.它们是完全不同的javascript对象,所以fooBars1 !== fooBars2.但是,它们是相同的不可变对象,所以Immutable.is(fooBars1, fooBars2) === true.

因此,为了防止重新渲染发生,您必须使用任何组件shouldComponentUpdate方法来检查旧的prop或state是否与新的prop或state相同.

shouldComponentUpdate(nextProps){
  return !Immutable.is(this.props.fooBars, next.props.fooBars);   
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您不想进行该检查,则不要换出基础记录.因为fooBar1!== fooBar2,将键1的值从fooBar1更改为fooBarN将永远不会产生相同的Immutable.如果不是交换记录,而是更新它们,您将获得原始对象,您可以使用===或pureRenderMixin.fooBars.updateIn([1,"id"],function(){return 1})=== fooBars (2认同)