In mobile friendly app development performance of App really matters. Any one extra render can affect the performance of our application.
Before getting into the solution first lets understand how react renders the changes and what causes the wasted render.
React re-renders the UI whenever
state associated with any component changes. And if this
state is passed as a
prop to components, then each component receiving this
state as a
objects are of non-primitive types. Which means they work on references. Whenever we pass, assign or compare objects, then we are not comparing the values instead we are comparing the references. To make it more clear
In React when we deal with objects we have to be extra attentive about using them in state and props.
Lets understanding this by an example.
To visualize extra render we can use
ReactDevTools . To enable visualization of render we have to turn on this feature. To do so Navigate to React Dev Tools and check the box which says Highlight updates when components render. Make sure it is checked. If you don’t have
react-dev-tools download it from here.
Consider following presentation-al component. It receives an
object pet as a prop and displays the data in UI.
DumbComponent is used by
App component to render pet info. In
App component there is a button on click of which we are assigning same information to an object.
Although, we are passing same information on click of button, even though both of the
DumbComponent will be rendered. The Green lines are showing re-rendering.
In class component we have
PureComponent which only re-renders the class component when there is a difference in shallow comparison of Props and state. Which in turn increases the performance of React app by saving few renders. But unfortunately it only work with
Class Components .
For functional component we have
React.memo(). It is a hoc which takes the component as parameter and returns the memoized version of it. React.memo() uses memoization in functional component in order to prevent extra render by proving referential equality.
React.memo()was introduced in 16.6 , so make sure you are using React v16.6 or later.
If we make our
DumbComponent memoized then we can save this extra rendering. Lets change
export default DumbComponent line to
export default React.memo(DumbComponent); and run our applicaiton.
We can see our
DumbComponent is now not rendering on every click. But our
App component is still re-rendering every time we click on button. Lets fix this as well by adding
Now we have prevented the extra re-rendering. We can that even though after multiple clicks on button as passing same object is not triggering the re-rendering.
Note: React.memo() do a shallow comparison of objects.
If we pass nested objects having same data then there will be extra re-render because React.memo() does only shallow comparison not the deep comparison.
We can resolve this by passing out own comparison handler to React.memo().
propsAreEqualfunction must return
nextProps are equal.
You may use React.memo() for all Presentational Components, but the component which are going to render for every prop change does not need
React.memo() . As by using
React.memo() we are forcing react to perform one more additional check on passed