evkline
evkline

Reputation: 1511

Updating Records on ImmutableJS OrderedMap without losing reference

I'm using an ImmutableJS OrderedMap to store ImmutableJS Records in a React app. I was wondering what the idiomatic way to handle updates that share the same values would be without losing reference to the Record was. For example, given the following code what would be the correct way to update the fooBars object at key 1 if the Record to update at key 1 held the same exact value as the current Record at key 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);

Upvotes: 1

Views: 3168

Answers (1)

Crob
Crob

Reputation: 15195

You are updating it the correct way.

The thing to remember is that every mutation action on an immutable results in a brand new object.

So, from your example:

fooBars = fooBars.set(fooBar1.id, fooBar1); 
fooBars2 = fooBars.update(fooBar2.id, fooBar2);

You now have 2 objects, fooBars1 and fooBars2. They are completely different javascript objects, so fooBars1 !== fooBars2. But, they are the identical immutable objects, so Immutable.is(fooBars1, fooBars2) === true.

So, to prevent re-rendering from happening, you have to tap into whatever components shouldComponentUpdate method to check that the old prop or state is the same as the new prop or state.

shouldComponentUpdate(nextProps){
  return !Immutable.is(this.props.fooBars, next.props.fooBars);   
}

Upvotes: 5

Related Questions