React's official document provide Immutability Helpers.
What would be some real world usage of such helpers? I think I am missing something really basic here.
Dealing with immutable data in JavaScript is more difficult than in languages designed for it, like Clojure. However, we've provided a simple immutability helper, update() , that makes dealing with this type of data much easier, without fundamentally changing how your data is represented.
Immutable. js allows us to detect changes in JavaScript objects/arrays without resorting to the inefficiencies of deep equality checks, which in turn allows React to avoid expensive re-render operations when they are not required. This means Immutable. js performance tends to be good in most scenarios.
Immutable. js is a library that supports an immutable data structure. It means that once created data cannot be changed. It makes maintaining immutable data structures easier and more efficient.
An immutable value or object cannot be changed, so every update creates new value, leaving the old one untouched. For example, if your application state is immutable, you can save all the states objects in a single store to easily implement undo/redo functionality.
React assumes that objects set in state are immutable, which means that if you want to add or remove some element inside your array you should create new one with added element keeping previous array untouched:
var a = [1, 2, 3];
var b = React.addons.update(a, {'$push': [4] });
console.log(a); // [1, 2, 3];
console.log(b); // [1, 2, 3, 4];
By using immutable objects you can easily check if content of object has changed:
React.createClass({
getInitialState: function () {
return { elements: [1, 2, 3] };
},
handleClick: function() {
var newVal = this.state.elements.length + 1;
this.setState({
elements: React.addons.update(this.state.elements, { '$push': [ newVal ] })
})
},
shouldComponentUpdate: function (nextProps, nextState) {
return this.state.elements !== nextState.elements;
},
render: function () {
return (
<div onClick={this.handleClick}>{ this.state.elements.join(', ') }</div>
);
}
});
ReactJS state should preferably be immutable. Meaning that, everytime render()
is called, this.state
should be a different object. That is: oldState == newState
is false and oldState.someProp == newState.someProp
is also false.
So, for simple state objects, there's no doubt they should be cloned. However, if your state object is very complex and deep, cloning the entire state might impact performance. Because of that, React's immutability helpers is smart and it only clones the objects that it thinks it should clone.
This is how you do it when you clone the state by yourself:
onTextChange: function(event) {
let updatedState = _.extend({}, this.state); // this will CLONE the state. I'm using underscore just for simplicity.
updatedState.text = event.text;
this.setState(updatedState);
}
This is how you do it when you let React's immutability helpers determine which objects it should actually clone:
onTextChange: function(event) {
let updatedState = React.addons.update(this.state, { text: {$set: event.text} });
this.setState(updatedState);
}
The above example will perform better then the first one when the state
is too complex and deep.
React application prefer immutability, there are two ways (from Facebook) to support immutability, one is to use immutable.js that is a complete immutability library, another one is the immutable helper that is a lightweight helper. You only need to choose one to use in one project.
The only disadvantege of immutable.js is that it leak itself throughout your entire application including the Stores and View Components, e.g.,
// Stores
props = props.updateIn(['value', 'count'], count => count + 1);
// View Components
render: function() {
return <div>{this.props.getIn("value", "count")}</div>;
}
If you use immutable helper, you can encapsulate the immutability operations at the place where updates happen (such as Stores and Redux Reducers). Therefore, your View Components can be more reusable.
// Stores or Reducers
props = update(props, {
value: {count: {$set: 7}}
};
// View Components can continue to use Plain Old JavaSript Object
render: function() {
return <div>{this.props.value.count}</div>;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With