最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React - using deep equality as to not re-render on object identity change - Stack Overflow

programmeradmin0浏览0评论

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 override shouldComponentUpdate as such. So perhaps have something like class DeepEqualityComponent extends React.Component, then extend from DeepEqualityComponent – strider Commented Apr 1, 2017 at 19:17
Add a ment  | 

1 Answer 1

Reset to default 2

I would not suggest you do this for the following reasons:

  1. 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.

  2. 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!

发布评论

评论列表(0)

  1. 暂无评论