React Performance - How To Avoid Redundant Re-Renders - by Iskander Samatov - ITNEXT
React Performance - How To Avoid Redundant Re-Renders - by Iskander Samatov - ITNEXT
Published in ITNEXT
Save
Redundant re-renders are a common issue in React. If not taken seriously, this issue
can quickly worsen the performance of your application.
By understanding and implementing these practices, you can avoid the problem and
keep your rendering process running smoothly.
d C llb k
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 1/13
27/05/2022, 08:59 React Performance: How to avoid redundant re-renders | by Iskander Samatov | ITNEXT
Let’s first cover the main toolkit under your belt for cutting down the re-renders: memo
and useCallback . You should know how these utility functions work in order to be able
memo is a utility method that React library provides to memoize the state of the
components and make it so that they only render when their props change. All you
need to do is wrap your components declaration with the function:
Now, the ListItem component will no longer re-render when its parent does. The only
time the ListItem would re-render is if the props passed to it change. This is especially
useful when working with large lists. List items will not re-render each time the state of
the parent list changes. This tweak could drastically improve the performance of your
UI.
So what about useCallback? In the previous example, our ListItem did not receive any
event handler props. Yet passing event handlers from parent to child is a common
pattern that you will, no doubt, use a lot when working with React.
There is, however, a slight problem with passing event handlers to memoized
components. Event handlers are usually declared inside of the parent component,
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 2/13
27/05/2022, 08:59 React Performance: How to avoid redundant re-renders | by Iskander Samatov | ITNEXT
which means they will re-render each time the parent component does. This will make
Open in app Get started
wrapping our child components with memo useless since the event handler prop will
cause it re-render each time anyway.
And that’s where useCallback comes in. This utility method returns a memoized
version of any callback function it receives. The only time it would recalculate the value
of the function you pass is if any of the dependencies you provided change.
Let’s see how we can use useCallback to pass an event handler to our ListItem
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 3/13
27/05/2022, 08:59 React Performance: How to avoid redundant re-renders | by Iskander Samatov | ITNEXT
In the example above, we wrapped the handleClick event handler with useCallback .
useCallback will memoize our handler function after the initial render. Next time our
parent list re-renders useCallback will return the same memoized version of our
handler function. The ListItem component will thus avoid a redundant re-rendering
since none of its props changed.
Note: Whenever you use memo to reduce re-renders for a component, be sure to also
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 4/13
27/05/2022, 08:59 React Performance: How to avoid redundant re-renders | by Iskander Samatov | ITNEXT
Note: Whenever you use memo to reduce re renders for a component, be sure to also
wrap the event handler properties that the component receives
Openwith
in app .
Get started
useCallback
For example, it’s rare for components to need to decide if they should render
themselves. It’s usually better for the parent components to make that decision.
When rendering lists, err on the side of providing strictly the props the list items need
to function. Try to avoid passing any of the state variables of the parent to the child.
Passing parent’s state variables will cause ALL of the list items to re-render each time
that variable changes. The negative effect of this is amplified as the size of your list
grows.
Instead, try to derive a primitive prop based on the updated state of the parent. This
way, the child components only need to re-render when the primitive changes.
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 5/13
27/05/2022, 08:59 React Performance: How to avoid redundant re-renders | by Iskander Samatov | ITNEXT
Here we have the ListItem for displaying items inside the List . ListItem accepts id ,
selectedId and title properties. We're also outputting the "Rendered" word to the
console each time the ListItem renders to see how many times it rendered. Note that
we're also wrapping our ListItem with memo to reduce the number of re-renders for
each item.
For the sake of the example, we’re setting selectedItemId to 2 inside the useEffect .
Doing so will trigger another re-render of the parent component after the initial
render.
After running the example above the console will output the word “Render” a total of
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 6/13
27/05/2022, 08:59 React Performance: How to avoid redundant re-renders | by Iskander Samatov | ITNEXT
After running the example above, the console will output the word “Render” a total of
6 times: 3 times during the initial render of each list item andOpen in apptimesGet
3 more started
when the
setSelectedItemId is called.
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 7/13
27/05/2022, 08:59 React Performance: How to avoid redundant re-renders | by Iskander Samatov | ITNEXT
In this example, ListItem receives the isSelected prop that lets it know whether the
item is selected. Now it's up to the parent List component to make that decision. As a
result, the word "Rendered" will only be printed 4 times. That's because the items that
weren't selected didn't re-render since none of their props changed.
While cutting down from 6 to 4 renders might not seem like a big deal, when you’re
working with large lists that render a lot of data and have sizeable component trees,
you can significantly improve their performance using this approach.
Better yet, try to extract the fields your component needs from the data structure as
primitive props. This will make it easier to optimize the performance of your
components in the future.
Let me show you what I mean. Say we have a Profile component that displays user
information:
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 8/13
27/05/2022, 08:59 React Performance: How to avoid redundant re-renders | by Iskander Samatov | ITNEXT
Nothing particularly terrible about this component. But, we should ask ourselves: “Do
we really need the whole pass the whole user object?”
Since we’re only using two fields from the object, we could accept them as primitive
props instead:
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 9/13
27/05/2022, 08:59 React Performance: How to avoid redundant re-renders | by Iskander Samatov | ITNEXT
If the user object got re-created, which can easily happen multiple times within the
component's lifetime, this will not cause re-renders for our Profile component.
Profile doesn't care if the user object gets recreated, as long as the values of the
title and name fields stay the same. Now it's much easier to optimize Profile by
wrapping it with memo .
Let’s look at an example. Say we have a UserList component that displays user
profiles. You can expand each profile to view more info:
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 10/13
27/05/2022, 08:59 React Performance: How to avoid redundant re-renders | by Iskander Samatov | ITNEXT
In the code above, we're using useEffect to track when we should be fetching
additional info but is that necessary? A simpler and more future-proof solution is to
fetch additional information inside of the expand click handler:
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 11/13
27/05/2022, 08:59 React Performance: How to avoid redundant re-renders | by Iskander Samatov | ITNEXT
The main reason this is better is that as the complexity of your component grows, you
might introduce other pieces of logic that will change selectedUserId but that don't
necessarily need to request additional info. If you're not careful, you might trigger
requests in cases where you didn't intend to.
Often using useEffect is justified and might even be the only viable solution. With that
said, I suggest double checking if you need useEffect . Sometimes you can get away
Conclusion
In this post, we looked at some of the practices for optimizing your React rendering
process. By following these tips, you can avoid unnecessary re-renderings and improve
the performance of your app I hope you find them useful!
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 12/13
27/05/2022, 08:59 React Performance: How to avoid redundant re-renders | by Iskander Samatov | ITNEXT
the performance of your app. I hope you find them useful!
148 6
Open in app Get started
If you would like more tips on writing better React code, check out my other post “
Simple tips for writing clean React components “.
If you’d like to get more web development, React and TypeScript tips consider
following me on Twitter, where I share things as I learn them.
Happy coding!
Subscribe
https://itnext.io/react-performance-how-to-avoid-redundant-re-renders-6a33618d92a3 13/13