Reactâs memo API can be used to optimize the rendering behavior of your React function components . We will go through an example component to illustrate the problem first, and then solve it with Reactâs memo API .
Keep in mind that most of the performance optimizations in React are premature. React is fast by default, so every performance optimization is opt-in in case something starts to feel slow.
Note: If your React component is still rendering with React memo, check out this guide about Reactâs useCallback Hook . Often a re-rendering is associated with a callback handler which changes for every render.
Note: Donât mistake Reactâs memo API with Reactâs useMemo Hook . While React memo is used to wrap React components to prevent re-renderings, useMemo is used to memoize values.
Letâs take the following example of a React application which renders a list of user items and allows us to add users to the list. We are using Reactâs useState Hook to make this list stateful:
If you include a console.log statement in the function body of the App, List, and ListItem components, you will see that these logging statements run every time someone types into the input field:
After typing into the input field, all the components re-render because the App component updates its state and all of its child components will re-render by default.
Thatâs the default behavior given by React and most of the time itâs fine to keep it this way as long as your application doesnât start to feel slow.
But once it starts to feel slow, such as rendering a huge list of items every time a user types into the input field, you can use Reactâs memo API to memoize your componentâs function :
Now when we type into the input field, only the App component re-renders because itâs the only component affected by the changed state. The List component receives its memoized props from before, which havenât changed, and thus doesnât re-render at all. The ListItem follows suit without using Reactâs memo API because the List component already prevents the re-render.
Thatâs Reactâs memo function in a nutshell. It seems like we donât need to memo the ListItem component. However, once you add an new item to the list with the button, you will see the following output with the current implementation:
By adding an item to the list, the list changes which causes the List component to update. For now thatâs the desired behavior because we want to render all the items (2 items) plus the new item (1 item). But perhaps it would be more efficient to render only the one new item instead of all the items:
After trying the scenario from before, by adding an item to the list, with the new implementation with Reactâs memo function, you should see the following output:
Only the new item renders. All the previous items in the list remain the same and thus donât re-render. Now only the components which are affected from the state changes rerender.
You might be wondering why you wouldnât use React memo on all your components or why React memo isnât the default for all React components in the first place.
Internally Reactâs memo function has to compare the previous props with the new props to decide whether it should re-render the component. Often the computation for this comparison can be more expensive than just re-rendering the component.
In conclusion, Reactâs memo function shines when your React components become slow and you want to improve their performance. Often this happens in data heavy components, like huge lists where lots of components have to rerender once a single data point changes.