Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

React discusses on this page about performance that you can use shallow equality and avoid mutating objects, so that components 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 component 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 component 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.

like image 606
tscizzle Avatar asked Apr 01 '17 19:04

tscizzle


People also ask

How do you prevent unnecessary re-renders in React?

1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.

How do you prevent re-rendering of components that have not changed?

Preventing Re-Renders: The Old Way To prevent the render method from being called, set the return to false, which cancels the render. This method gets called before the component gets rendered. Sometimes you may want to prevent re-render even if a component's state or prop has changed.

Does React re-render everything on state change?

React components automatically re-render whenever there is a change in their state or props. A simple update of the state, from anywhere in the code, causes all the User Interface (UI) elements to be re-rendered automatically.

Will a React component reset its state when it re-renders?

As we already saw before, React re-renders a component when you call the setState function to change the state (or the provided function from the useState hook in function components). As a result, the child components only update when the parent component's state changes with one of those functions.


1 Answers

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

  1. Deep comparisons are costly. So everytime something changes you will have to do a deep comparison 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 components. 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!

like image 171
aks Avatar answered Oct 17 '22 11:10

aks