📖 Notes
LESSON 14 OF 18
React.memo, useMemo & useCallback
Skipping Renders That Don't Need to Happen
React.memo, useMemo, and useCallback all exist to avoid unnecessary re-renders and recalculations — but they're an optimisation for a real performance problem, not something to add everywhere by default.
Three Optimisation Tools
memo, useMemo, useCallback
🧊
React.memo(Component)
Skips re-rendering a component if its props haven't changed.
🧮
useMemo(fn, [deps])
Caches an expensive calculation, only recomputing when dependencies change.
📎
useCallback(fn, [deps])
Caches a function reference so it doesn't cause unnecessary child re-renders.
⚠️
Warning
Overusing these adds complexity for little benefit — profile first, optimise second.
Memoized Dashboard
JSXimport { memo, useMemo, useCallback } from "react";
// memo — skip re-render if props unchanged
const CourseCard = memo(function CourseCard({ title, lessons }) {
return <div>{title} · {lessons} lessons</div>;
});
function Dashboard({ courses, filter }) {
// Cache expensive computation
const filtered = useMemo(
() => courses.filter(c => c.cat === filter),
[courses, filter]
);
// Stable function reference
const handleEnroll = useCallback((id) => {
enrollAPI(id);
}, []);
return filtered.map(c => <CourseCard key={c.id} {...c} onEnroll={handleEnroll} />);
}
⚠️
Profile first, optimise second
Adding memo/useMemo/useCallback everywhere adds complexity without necessarily improving performance. Use React DevTools Profiler to find actual re-render problems before reaching for these tools.