The Journey of #100DaysOfCode (@sourabhbagrecha)

#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:

3 Likes