If you open your console and switch between Members and Dashboard, you can see a console log that says Header is being updated and it says that every time you switch the route.

Why, though?

Our Header doesn’t use any props at all. I don’t want to re-render it, not ever in this case.

React.memo(Component)

I guess most of you have heard about the memo higher order component. You wrap your Component in it, it triggers render only when the component’s props change, all is nice and dandy.

React.memo() does a shallow comparison. Let’s say you’ve got some MemberList component which updates based on your members array somewhere in your distant store. MemberList renders MemberRow for each member object and gets it as a prop.

You have 10 members. You add a new one. You create a new array. Each MemberRow re-renders although you’re wrapping it in a memo() . The shallow comparison sees that the object is a new one — it doesn’t care that the data stayed the same. It will trigger another render although you just need to add new MemberRow for the member you just added and you don’t need to refresh the other 10 MemberRow s.

React.memo(Component, propsAreEqual)

But wait, you can provide second argument to React.memo()!

Now that’s something I couldn’t find in the articles I kept reading. All were saying how awesome memo() is but never showed any REAL real world examples, where shallow comparison is sometimes not enough. I had to read the docs about 4 times to actually find this, not counting the articles I kept binging.

function MyComponent(props) {

/* render using props */

}

function areEqual(prevProps, nextProps) {

/*

return true if passing nextProps to render would return

the same result as passing prevProps to render,

otherwise return false

*/

}

export default React.memo(MyComponent, areEqual);

So you can also pass a function that checks previousProps and nextProps . That allows you to do an another kind of comparison — for example using JSON.stringify() if you want to make sure that your data indeed matches and do not wish to trigger a re-render.

I also created a higher order component for this, which I’ll show/link at the end of the article.

Now let’s get back to my ever-updating <Header /> component from the code sandbox.

Wrapping it in a memo() won’t do a thing

That’s right, because as I said, it receives no props. Yet, it’s updating. Why is that?

Because the whole Layout is updating.

I updated the fiddle a little, let’s have a look