#Day86 of 100daysofcode
Today I learned comparator custom comparator functions in React.memo HOC(higher-order components).
Because of our React.memo optimization yesterday, our list items won’t get re-render if their parent re-renders.
We can see this in React Devtools’ Profiler as below:
Suppose we want to have a feature in our app, where any time the user hovers over any one of those list items, they will get highlighted as shown below:
Now every time a user hovers over any list item the complete list along with every list item in it will get re-rendered because every ListItem
component has a prop called highlightedIndex as we have seen yesterday.
Let’s take a look at our Profiler again when we hover over any item in the list:
But we don’t want to re-render all the items in the list because all of them have no visible UI updates to reflect in the DOM. We just want to update the list item that has been highlighted or which was highlighted before but it’s no longer highlighted.
For cases like these where the component’s props have changed but we still want to re-render only when a specific condition takes place, we can use Comparator Functions.
Let’s see it in action:
ListItem = React.memo(ListItem, (prevProps, nextProps) => {
if (prevProps.getItemProps !== nextProps.getItemProps) return false
if (prevProps.item !== nextProps.item) return false
if (prevProps.index !== nextProps.index) return false
if (prevProps.selectedItem !== nextProps.selectedItem) return false
if (prevProps.highlightedIndex !== nextProps.highlightedIndex) {
const wasPrevHighlighted = prevProps.highlightedIndex === prevProps.index
const isHighlightedNow = nextProps.highlightedIndex === nextProps.index
return wasPrevHighlighted === isHighlightedNow
}
})
In the above implementation, we are passing a comparator function as the second argument to React.memo
that will accept two parameters ( prepProp
& nextProp
).
Both these parameters will include prop state(before and after) whenever a re-render get triggered for the concerned component.
Here we are checking if any of the props other than highlightedIndex change, we simply need to re-render this component, so we are simply returning false
to tell React that this component need to re-render.
But what about the highlightedIndex
prop, well we are still checking whether it is changed or not but along with that we will also check whether the component that is in consideration has anything to do with the change in the highlightedIndex. If the listItem doesn’t need to be highlighted or un-highlighted based upon its own index we won’t re-render it, otherwise we will re-render it.
Now, I will hover over a few list items one-by-one and you can see in the profiler that only the affected components(as per the highlightedIndex prop) in the list are being re-rendered, otherwise, all the other listItem will remain as-is, which is a great performance boost: