React.memo() is a higher-order component (HOC) used to optimize React functional components. It memoizes the rendered output and prevents unnecessary re-renders when the component's props have not changed, essentially acting as the functional equivalent of PureComponent in class-based React.
// Basic syntax wrapping a component
const MemoizedComponent = React.memo(MyComponent);
// Syntax with custom comparison function
const MemoizedComponent = React.memo(MyComponent, arePropsEqual);
1. The Child Component (Memoized)
// Child.js - This component only re-renders if 'name' changes
import React from "react";
const Child = ({ name }) => {
console.log("Child Rendered");
return <div>Hello, {name}!</div>;
};
// Export the component wrapped in React.memo
export default React.memo(Child);
2. The Parent Component
// Parent.js - Manages state
import React, { useState } from "react";
import Child from "./Child";
const Parent = () => {
const [count, setCount] = useState(0);
const [name, setName] = useState("User");
return (
<div>
<h1>Count: {count}</h1>
// Clicking this updates Parent state but NOT Child props
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<Child name={name} />
</div>
);
};
export default Parent;
Sometimes shallow comparison isn't enough (e.g., nested objects). You can pass a second argument to control exactly when to re-render.
// Custom comparison function
function arePropsEqual(prevProps, nextProps) {
// Return true if passing nextProps to render would return
// the same result as passing prevProps to render,
// otherwise return false
return prevProps.userId === nextProps.userId;
}
export default React.memo(ProfilePage, arePropsEqual);
Without Memo: Parent renders ➜ Count updates ➜ Parent Re-renders ➜ Child Re-renders (wasted).
With Memo: Parent renders ➜ Count updates ➜ Parent Re-renders ➜ React checks Child props ➜ Props are same? ➜ Skip Child Re-render.
Control the parent state and observe when the child component "flashes" (re-renders).
State (Count): 0
Prop (Name): User
*A yellow flash indicates a re-render occurred.
React.memo if you spot performance issues. Memoization has its own cost.useCallback in the parent, or React.memo will see a "new" function every time and re-render anyway.console.log in the child.React.memo and watch the console logs stop appearing every second.