React
Beginner
1 min read
Profiling and Avoiding Unnecessary Re-renders
Example
import React, { useState, memo, useCallback, useMemo } from 'react';
// ── Expensive pure component ───────────────────────────────────────────────
const Row = memo(function Row({ item, onRemove }) {
console.log(`Rendering row ${item.id}`);
return (
<li>
{item.label}
<button onClick={() => onRemove(item.id)}>✕</button>
</li>
);
});
// ── Parent state is isolated so only changed rows re-render ────────────────
function ItemList({ rawItems, filterText }) {
const [removedIds, setRemovedIds] = useState(new Set());
// Stable callback – does not change on re-render
const handleRemove = useCallback(id => {
setRemovedIds(prev => new Set([...prev, id]));
}, []);
// Expensive filter recomputed only when inputs change
const visibleItems = useMemo(
() => rawItems
.filter(i => !removedIds.has(i.id))
.filter(i => i.label.toLowerCase().includes(filterText.toLowerCase())),
[rawItems, removedIds, filterText]
);
return (
<ul>
{visibleItems.map(item => (
<Row key={item.id} item={item} onRemove={handleRemove} />
))}
</ul>
);
}