The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Use memo, useMemo, and useCallback only when profiling shows that a component render or calculation is costly and avoidable. memo can let a component skip rendering when its props are unchanged; useMemo caches a calculation result; and useCallback keeps a function’s identity stable. None guarantees faster code, and React Compiler can now automate many of these optimizations.
What each React memoization tool can skip
| Tool | What it can avoid | When it can help |
|---|---|---|
memo |
A component render when its props are unchanged. | A profiled, expensive child often receives the same props. |
useMemo |
Repeating a calculation when its dependencies are unchanged. | A costly calculation runs during rendering, or a stable object or array prop is needed for a memoized child. |
useCallback |
A changed function identity between renders. | A callback is passed to a memoized child or used as a Hook dependency and its identity needs to remain stable. |
These tools address different work. They are performance optimizations, not correctness tools: React’s documentation describes memo as a performance optimization, not a guarantee and says to rely on useMemo only as a performance optimization.
Why a memoized child may still render
By default, memo compares each prop with Object.is. If a parent creates a new object, array, or function while rendering, that prop has a new identity even when its contents or behavior look equivalent. The memoized child therefore sees a changed prop and may render.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesA common chain looks like this: a parent renders, creates a fresh value or callback, and passes it to a memoized child. To give the child a chance to skip rendering, stabilize the value with useMemo or the callback with useCallback. The child can skip only if its other relevant props are unchanged too.
#1 Best Overall
memo does not block a render caused by the child’s own state or by context it reads. A custom comparison function is available when the default prop comparison is insufficient, but it introduces another piece of logic to maintain and should be considered only after measurement.
Stabilize a calculated value with useMemo
useMemo caches the result of a calculation between renders while its dependencies remain unchanged. React compares each dependency with Object.is. Include every reactive value used by the calculation in the dependency list.
Rank #2
const visibleItems = useMemo(() => filterItems(items, query), [items, query]);
This example can avoid repeating filterItems when neither items nor query changed. It can also give a memoized child a stable array prop, provided the dependencies remain stable and the child’s other props do not change.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchKeep the calculation pure: it should compute a result from its inputs rather than cause side effects. Do not use a memoized value to conceal incorrect behavior or make rendering depend on a cache being present.
Stabilize a callback with useCallback
useCallback caches a function definition while its dependencies remain unchanged. It does not prevent JavaScript from evaluating the function expression during rendering; it preserves the function identity React returns when the dependencies are the same.
const handleSelect = useCallback((id) => {
setSelectedId(id);
}, []);
Use this when a stable callback matters, such as when passing it to a memoized child. If the callback reads reactive values, include those values as dependencies so it does not use stale data. React compares dependencies with Object.is.
Rank #4
Diagnose the slowdown before adding memoization
- Reproduce the sluggish interaction. Identify the specific action that feels slow rather than optimizing components based on appearance alone.
- Profile the interaction. Use the React Developer Tools Profiler to find which renders or calculations consume meaningful time.
- Check simpler causes. Look for Effects that set state and trigger extra renders, state placed higher in the tree than necessary, and props whose object, array, or function identities are always new.
- Make the smallest measured change. Apply the relevant memoization tool, then profile the same interaction again and check that the behavior remains correct.
React recommends prioritizing pure rendering, keeping state appropriately local, and avoiding unnecessary Effects. If an object or function is only needed inside an Effect, moving it inside that Effect—or outside the component when appropriate—can be simpler than memoizing it just to control Effect dependencies.
When manual memoization is unnecessary
- The component or calculation is already fast, and profiling does not show it as a meaningful cost.
- The props or dependencies change on most renders, so the cache rarely avoids work.
- Memoization adds complicated dependency lists or obscures straightforward code.
- The real issue is repeated state updates, an unnecessarily broad state owner, or an Effect that causes extra renders.
- React Compiler is enabled and handles the optimization automatically.
React’s current guidance is not to add memoization everywhere. The React Compiler introduction explains that the compiler can automatically memoize components, values, and functions. For new code, React recommends relying on the compiler where it is enabled; manual memo, useMemo, and useCallback remain available when you need precise control.
Best Value
A practical decision rule
- If a profiled child spends significant time rendering despite unchanged props, consider
memo. - If a profiled calculation is expensive and its inputs often remain unchanged, consider
useMemo. - If a callback’s changing identity prevents a memoized child from skipping a render, consider
useCallback. - If none of these conditions applies, prefer simpler code and revisit optimization only when a real performance problem appears.
For the broader compiler behavior and setup context, see React’s React Compiler documentation.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

