React discusses on this page about performance that you can use shallow equality and avoid mutating objects, so that ponents need only to check references to see if props or state changed.
I'm actually wondering about the opposite: is it possible to have the equality check use deep equality and ignore when the object references change (as long as their contents don't change)?
Reason is, I have a library which returns a cloned version of some internal variables, and to see updates on those variables, I need to re-ask for that internal variable, thus getting a fresh new clone. So I'll get entirely different objects by reference, but they could have not changed any of their fields. But every time I request such an update, React thinks everything has changed because all the references changed, and it re-renders a lot of unnecessary stuff.
Current solution: threw this in a ponent to stop it from rendering as long as the objects' fields don't change
shouldComponentUpdate(nextProps, nextState) {
return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState);
}
which does the trick since lodash's isEqual
equality check is deep, but I'd have to do that on each ponent that wants this behavior. I wonder if there's either a
- preferred way of achieving this
- an anti-pattern I'm using which leads to this in the first place and I could avoid it entirely
or maybe the above method is best.
React discusses on this page about performance that you can use shallow equality and avoid mutating objects, so that ponents need only to check references to see if props or state changed.
I'm actually wondering about the opposite: is it possible to have the equality check use deep equality and ignore when the object references change (as long as their contents don't change)?
Reason is, I have a library which returns a cloned version of some internal variables, and to see updates on those variables, I need to re-ask for that internal variable, thus getting a fresh new clone. So I'll get entirely different objects by reference, but they could have not changed any of their fields. But every time I request such an update, React thinks everything has changed because all the references changed, and it re-renders a lot of unnecessary stuff.
Current solution: threw this in a ponent to stop it from rendering as long as the objects' fields don't change
shouldComponentUpdate(nextProps, nextState) {
return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState);
}
which does the trick since lodash's isEqual
equality check is deep, but I'd have to do that on each ponent that wants this behavior. I wonder if there's either a
- preferred way of achieving this
- an anti-pattern I'm using which leads to this in the first place and I could avoid it entirely
or maybe the above method is best.
Share Improve this question asked Apr 1, 2017 at 19:05 tscizzletscizzle 12.3k16 gold badges59 silver badges98 bronze badges 1-
2
If you wanted this as the default behavior for a set of ponents, perhaps you could extend
React.Component
and overrideshouldComponentUpdate
as such. So perhaps have something likeclass DeepEqualityComponent extends React.Component
, then extend fromDeepEqualityComponent
– strider Commented Apr 1, 2017 at 19:17
1 Answer
Reset to default 2I would not suggest you do this for the following reasons:
Deep parisons are costly. So everytime something changes you will have to do a deep parison and then do the rendering part. We would just be better off letting react do the rendering cause it was made for it.
As for the case of handling it in all the ponents. We can avoid this problem by destructuring the object thus sending smaller props, now the react can handle the optimised re-renders. eg:
<Footer data={object} />
<Footer title={object.title} copyright={object.copyright}/>
I hope that helps!