Skip to content

Instantly share code, notes, and snippets.

@ethan-deng
Last active October 9, 2016 03:51
Show Gist options
  • Select an option

  • Save ethan-deng/a7335a8f6200186ed418 to your computer and use it in GitHub Desktop.

Select an option

Save ethan-deng/a7335a8f6200186ed418 to your computer and use it in GitHub Desktop.

The case that you have to use Immutable.js in React

In React, there are scenarios that you have to use Immutable.js if you want to use shouldComponentUpdate to improve performance.

For example if your state is an object or array in a flux data store

  this.var1 = {a:1, b:2};
  this var2 = [1,2,3];

In an event which changes the state

  onClickEvent: function(){
    this.var1.b = 1000;
    this.var2.push(4);
  }

in the component

  shouldComponentUpdate: function(nextProps, nextState) {
    if (nextProps.var1 == this.props.var1){
      return false;
    }
    else{
      return true;
    }
  },

or

shouldComponentUpdate: function(nextProps, nextState) {
    if (nextProps.var2 == this.props.var2){
      return false;
    }
    else{
      return true;
    }
  },

Both implementation will always return false and UI will not updated because the variable reference doesn't change: var1 is still var1 and var2 is still var2.

If you do deep copy of object or array, the issue will be gone. For example

onClickEvent: function(){
  this.var1 = deepCopy(this.var1);
  this.var1.b = 1000;
  
  this.var2 = [].concat(this.var2);
  this.var2.push(4);
}

Since now the variable reference is different. However deep copy is expensive and should be avoid. Another point is that if you always do a deep copy of state, there is "almost" no need to use shouldComponentUpdate since the comparing of the previous state and current state will always return false even when the operation result in same values. By saying "Almost", I mean using shouldComponentUpdate is still good since the app's state change may not change the state of this component (deep copy may not happen), if deep copy doesn't happen it is still a good thing to stop update of the component.

You use immutable.js to fine tune the performance to the level of the values inside a varialbe/state. If this fine tune is not really necessary then you can safely skip immutable.js and keep using the deep copy approach. When most of the operations on the specific state/variable will result in an UI update, then there is really no point to fine tune to this level (the only thing you will save is the cost of deep copy) and avoid the hassle of immutable.js all together.

onClickEvent: function(){
  this.var1 = this.var1.set('b', 1000);
  this.var2 = this.var2.push(4);
}

immutable.js will make sure the varialbe reference is different (shouldComponentUpdate will return true) but if the operation result in the same value the variable reference will be the same (shouldComponentUpdate will return false).

Another notice is that when using immutable.js you must do a "copy" of the variable to create a new reference in order to make sure the shouldComponentUpdate will do a "deep" comparison of the previous state and current state. In other words, this is wrong.

onClickEvent: function(){
  this.var1.set('b', 1000);
  this.var2.push(4);
}

Comparing previous state and current state will always return true, even the value of the state has changed since the reference used in the state doesn't change.

Conclusion

The conclusion is that Immutable.js is hard to program right and when it is not used correctly, there is no performance gain. Use deep copy approach and use shouldUpdateComponent to compare the references will be good enough for many projects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment