React.memo vs useMemo
React.memo is a higher-order component that skips re-rendering when props haven't changed. useMemo is a hook that memoizes a computed value inside a component.
Side-by-Side Comparison
| Feature | React.memo | useMemo |
|---|---|---|
| What it is | Higher-order component (HOC) | React hook |
| What it memoizes | Component render output | A computed value |
| Where it's used | Wraps component definition | Inside component body |
| Comparison basis | Shallow prop comparison | Dependency array |
| Prevents | Unnecessary re-renders | Unnecessary recalculation |
Code Examples
React.memo
- Higher-order component — wraps the entire component
- Prevents re-rendering when props are shallowly equal
- Compares PROPS only (not state or context)
- Optional custom comparison function
// Without memo: re-renders every time Parent renders
// With memo: skips re-render if props unchanged
const ExpensiveList = React.memo(function ExpensiveList({
items,
onSelect,
}) {
return items.map(item => (
<Item key={item.id} item={item} onSelect={onSelect} />
))
})
// Custom comparison
const Chart = React.memo(ChartComponent, (prev, next) => {
return prev.data.length === next.data.length
})useMemo
- Hook — used INSIDE a component
- Memoizes a computed VALUE (not the component itself)
- Recalculates only when dependencies change
- Avoids expensive recalculation on every render
function Dashboard({ transactions }) {
// Only recalculates when transactions change
const summary = useMemo(() => {
return {
total: transactions.reduce((s, t) => s + t.amount, 0),
count: transactions.length,
avg: transactions.reduce((s, t) => s + t.amount, 0)
/ transactions.length,
}
}, [transactions])
return <SummaryCard {...summary} />
}When to Use Which
React.memo
When a child component re-renders frequently due to parent renders but its own props rarely change. Most impactful on components with expensive render trees.
useMemo
When you have an expensive computation inside a component that doesn't need to run on every render. Also for stabilizing object/array references passed to memoized children.
Common Mistakes
- Using React.memo on components that receive new object/array/function props every render — memo does shallow comparison, so new references always cause re-render
- Wrapping everything in React.memo — adds overhead for components that almost always re-render with different props anyway
- Confusing the two — React.memo prevents RE-RENDERING, useMemo prevents RE-COMPUTATION within a render
Interview Questions
How do React.memo and useMemo work together?
useMemo stabilizes values (objects, arrays) passed as props. React.memo on the child then detects that the prop references haven't changed and skips re-rendering. Without useMemo, new object references would defeat React.memo's shallow comparison.
When would React.memo actually hurt performance?
When props change on almost every render, React.memo adds the cost of comparison without any benefit — it still re-renders plus now also runs the comparison. Also on very cheap components where the render cost is less than the comparison cost.