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.