TL;DR: React.memo is a higher order component that you can use to ensure functional components only re-render when the props change (much like PureComponent for class components). It’s a tool you can use for improving performance in your React applications.
Let’s say we’ve created a simple component that displays information about a user.
// User.jsx
import React from "react";
const User = ({ avatar, name }) => {
return (
<div>
<img src={avatar} />
<p>
Logged in as <strong>{name}</strong>
</p>
</div>
);
};
export default User;
Our application displays both the users information and the current time (which is updated every second).
// App.jsx
import React, { Component } from "react";
import User from "./User";
class App extends Component {
state = {
date: new Date(),
user: {
avatar: "/avatars/rob.jpg",
name: "Rob"
}
};
componentDidMount() {
setInterval(() => {
this.setState({
date: new Date()
});
}, 1000);
}
render() {
const { date, user } = this.state;
return (
<div>
<p>
The time is <strong>{date.toLocaleTimeString()}</strong>
</p>
<User {...user} />
</div>
);
}
}
Using console.log we can easily check to see whenever the <User /> component renders.
// User.jsx
const User = ({ avatar, name }) => {
console.log("Rendering <User />");
return (
<div>
<img src={avatar} />
<p>
Logged in as <strong>{name}</strong>
</p>
</div>
);
};
If you check the development console in your browser, you’ll see that the <User /> component is rendered every second when the the time is updated.
11:47:00 Rendering <User />
11:47:01 Rendering <User />
11:47:02 Rendering <User />
11:47:03 Rendering <User />
11:47:04 Rendering <User />
In an application this small the performance hit is going to be negligible. However, once your project reaches a certain size, you’ll want to make sure that you avoid and unnecessary re-renders for the sake of speed.
Previously, you could only avoid this situation by converting your functional component to a class component which extends React.PureComponent. React.memo provides a higher order component which prevents re-rendering from happening unless the props change.
To use it, simply wrap the component using React.memo before you use it.
import React from "react";
const User = ({ avatar, name }) => {
console.log("Rendering <User />");
return (
<div>
<img src={avatar} />
<p>
Logged in as <strong>{name}</strong>
</p>
</div>
);
};
export default React.memo(User);
You should now see that Rendering <User /> is only displayed once for the initial render.