Topic 45 of 54
Skipping Renders
Overview
`React.memo` is a Higher Order Component (HOC) that wraps around a functional component. It tells React: 'Only re-render this component if its props have actually changed since the last render.' It breaks the cascade effect. If the parent renders but passes the exact same props to the child, the child simply skips the render phase and re-uses the previous UI.
Syntax
React does a 'shallow comparison' (using Object.is) on the old props vs new props. If they are equal, it skips rendering.
Wrapping a Component in memo
jsx
import { memo, useState } from 'react';
// 1. Wrap the function in memo()
const ExpensiveChart = memo(function ExpensiveChart({ data }) {
console.log("ExpensiveChart rendered!");
// ...heavy SVG math here
return <svg>...</svg>;
});
function Dashboard() {
const [clicks, setClicks] = useState(0);
const chartData = [1, 2, 3]; // Static data
return (
<div>
<button onClick={() => setClicks(c => c + 1)}>Click: {clicks}</button>
{/*
Because chartData doesn't change, ExpensiveChart will ONLY
render once on mount, and then skip all subsequent renders!
*/}
<ExpensiveChart data={chartData} />
</div>
);
}Common Pitfalls
- Premature Optimization: Wrapping *every* component in `React.memo`. Memoization has a cost (React has to run the comparison algorithm). Only use it on heavy components that are demonstrably causing lag.
- Passing inline objects or functions to a memoized component. They have new memory references on every render, immediately breaking the memoization.
Interview Tips
- Understand 'Shallow Comparison'. If you pass a brand new object literal `{ name: 'Alice' }` or an inline arrow function `() => doSomething()` as a prop, `React.memo` will fail to stop the render because `{}` !== `{}` in JavaScript memory.
Real-World Example
Memoizing a single row in a massive list of 10,000 items. If you update the data in Row 5, you don't want Rows 1-4 and 6-10000 to re-render.
example
jsx
const TableRow = memo(function TableRow({ item, onSelect }) {
return (
<tr onClick={() => onSelect(item.id)}>
<td>{item.name}</td>
<td>{item.price}</td>
</tr>
);
});