React.memo is a higher-order component that wraps a function component and prevents unnecessary re-renders by performing a shallow comparison of the component's props before deciding whether to re-render.
How it works step-by-step:
Object.is for each prop)Basic usage:
1const UserCard = React.memo(({ name, age, onUpdate }) => {2 console.log("UserCard rendered");3 return (4 <div>5 <h3>{name}</h3>6 <p>Age: {age}</p>7 <button onClick={onUpdate}>Update</button>8 </div>9 );10});1112// Parent component13function App() {14 const [count, setCount] = useState(0);15 const [user, setUser] = useState({ name: "Alice", age: 30 });1617 // UserCard will NOT re-render when count changes18 // because user object reference stays the same19 return (20 <div>21 <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>22 <UserCard23 name={user.name}24 age={user.age}25 onUpdate={() => setUser({...user, age: user.age + 1})}26 />27 </div>28 );29}
Custom comparison function:
You can provide a custom areEqual function as the second argument to control when re-renders should be skipped:
1const UserCard = React.memo(2 ({ user, onClick }) => (3 <div onClick={onClick}>4 <h3>{user.name}</h3>5 </div>6 ),7 (prevProps, nextProps) => {8 // Only re-render if user.id or onClick changed9 return (10 prevProps.user.id === nextProps.user.id &&11 prevProps.onClick === nextProps.onClick12 );13 }14);
When to use React.memo:
When NOT to use React.memo:
Critical pitfall — reference equality: React.memo does shallow comparison. If you pass new object or function references on every render, React.memo won't help because it sees them as "changed". You must combine React.memo with useCallback (for functions) and useMemo (for objects/arrays):
1// Without useCallback — new function every render, memo is useless2const handleClick = () => doSomething(id);3<MemoizedChild onClick={handleClick} />45// With useCallback — stable reference, memo works correctly6const handleClick = useCallback(() => doSomething(id), [id]);7<MemoizedChild onClick={handleClick} />
Performance note: React.memo only checks props — it does not prevent re-renders caused by state or context changes within the component itself.