After updating props, this.props is always === nextProps / prevProps
You could use Immutable.js. It is a library that Facebook made to work with react/flux. https://facebook.github.io/immutable-js/
We have been stumped by this a couple of times.
shouldComponentUpdate(nextProps) {
return this.props.myObj !== nextProps.myObj
}
Many times, some value inside the myObj object would change. However the above function would return false. The reason being that both this.props.myObj
and nextProps.myObj
were referencing/pointing to the same object.
By implementing Immutable.js, the data will always be passed down as clones (instead of referencing the same object, they will actually be separate objects).
It re-enforces flux's uni-directional flow. You will never be able to (accidentally) modify the original data that is being passed into your component (whether as props or from a flux store).
This also enables you to use a PureRenderMixin – which automatically stops the render if the values of state/props have not changed. This could help with performance.
===
will check if it's the same object. It seems that what you're doing is mutating the value that the boxes
property points to.
Something like this occurred for me using Flux Stores to store my state in the manner suggested by the official Todo List tutorial (http://facebook.github.io/flux/docs/todo-list.html). For anyone else finding this after following the tutorial, a problem seems to arise in the TodoStore in the getAll() method, because it returns a direct reference to the internal data object:
getAll: function() {
return _todos;
}
This seems to breaks the ability of the lifecycle methods like componentDidUpdate(prevProps) to distinguish between the old and new props. I think the reason is that by passing a direct reference to the Store's data object into the views, the state/props effectively change immediately when the Store changes rather than after new values are passed down through the lifecycle methods, so old and new props always contain the same values. This could be solved by passing a copy of the internal data object _todos rather than the object itself,
for example, when _todos is an object,
getAll: function() {
return JSON.parse(JSON.stringify(_todos));
}
If _todos is an array, return _todos.slice() can be used instead.
In general, if using a Store to contain state information and call it from your controller-views, it seems advisable to return a copy of the data rather than a reference to the original, since the original will be mutated when state changes occur.