Component Patterns and Context APILesson 4.4
React.memo and performance optimization for components
React.memo, shallow comparison, when to use memo, memo with custom comparator, memo vs useMemo, unnecessary re-renders, profiling with React DevTools
React.memo: Skip Unnecessary Re-renders
By default, a child component re-renders whenever its parent re-renders — even if its props haven't changed. React.memo is a HOC that wraps a component and skips re-rendering if props are shallowly equal to the previous render.
Basic Usage
import { memo, useState } from 'react';
const ExpensiveList = memo(function ExpensiveList({ items }) {
console.log('List rendered');
return (
<ul>{items.map(i => <li key={i.id}>{i.name}</li>)}</ul>
);
});
function App() {
const [count, setCount] = useState(0);
const items = [{ id: 1, name: 'Item 1' }]; // stable reference needed
return (
<>
<button onClick={() => setCount(c => c + 1)}>{count}</button>
<ExpensiveList items={items} />
</>
);
}Custom Comparator
const List = memo(ExpensiveList, (prevProps, nextProps) => {
// Return true to SKIP re-render (props are equal)
return prevProps.items.length === nextProps.items.length;
});Shallow comparison means object references are compared, not deep values. If the parent recreates an array or object on every render, memo won't help — combine with useMemo for stable references. Profile first with React DevTools before applying memo.
