Master React.memo, useCallback & useMemo to Supercharge Component Performance
This article explains how React.memo, its second‑argument comparator, and the related hooks useCallback and useMemo can be used to avoid unnecessary re‑renders, handle function props correctly, and dramatically improve rendering performance in complex functional components.
React.memo
Before React 16.6, function components lacked a built‑in way to skip re‑execution like shouldComponentUpdate or PureComponent. Developers had to rely on conditional rendering or higher‑order components, and function components were compiled to a single createElement call.
With the introduction of React.memo in 16.6, function components gain a PureComponent -like optimization. The basic usage is:
const C = (props) => {
return <section>{props.name}你太美</section>
}
export default React.memo(C)When the parent re‑renders, C will shallow‑compare its props; if every prop value is identical, the component’s function is skipped, reducing unnecessary work.
Second Argument of memo
The optional second argument is a comparator function receiving nextProps and prevProps. Returning true tells React the props are equal, preventing a re‑render; returning false forces the component to update.
memo(IfEqual, () => false);If the comparator always returns false, the wrapped component will re‑execute on every render.
Function Props in Function Components
Functions are reference types, so even identical inline functions are not ===. Passing an inline onClick handler creates a new function each render, causing shallow comparison to fail.
const handleClick = () => {};
export default () => (
<div>
<IfEqual onClick={handleClick} />
</div>
);To avoid this, move the function definition outside the component or use memo 's second argument to ignore the function prop when appropriate.
useCallback
useCallback(fn, deps)memoizes a function based on its dependency array. When dependencies stay the same, the same function instance is returned, preventing unnecessary re‑creation.
const handleClick = useCallback(() => {
console.log(dep);
}, [dep]);If dep never changes, handleClick remains identical across renders; changing dep produces a new function.
useMemo
useMemo(() => value, deps)caches the result of an expensive computation. It is equivalent to useCallback(fn, deps) when the cached value is a function.
const a = useMemo(() => memorizeValue, [deps]);Example of a heavy computation:
function slowlyAdd(n) {
console.time('add slowly');
let res = n;
for (let i = 0; i < 2000000000; i++) {
res += 1;
}
console.timeEnd('add slowly');
return res;
}A custom hook can memoize this expensive result:
function useSlowlyAdd(n) {
const res = useMemo(() => slowlyAdd(n), [n]);
return res;
}Using useMemo ensures the heavy calculation runs only when its dependency n changes, keeping the UI responsive.
Higher‑Order Component with useMemo
Even a HOC can be created with useMemo:
const HOC = useMemo(() => <C />, deps);Final Thoughts
Wrapping large components (e.g., a 100k‑node Big component) with React.memo and ensuring stable function props with useCallback can dramatically improve mount and update performance, but over‑optimizing components that don’t benefit can actually degrade performance.
When a prop is a function, the only way to keep it stable is to define it outside the component or memoize it with useCallback .
Performance charts (images omitted) illustrate the speed gains when Big is memoized versus not memoized.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Tencent IMWeb Frontend Team
IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
