What does React.memo() do?
What React.memo() does
React.memo() is a wrapper for a function component
that tells React:
"If the props haven't changed, don't re-render this component again."
Syntax
const MemoizedComponent = React.memo(MyComponent);or directly:
export default React.memo(function MyComponent(props) {
return <div>{props.value}</div>;
});How it works
On every render, React compares the props of the new and the previous call of the component. If the props are equal by shallow comparison:
- the component is not called again;
- the previously rendered tree is returned.
Example:
function Child({ value }) {
console.log('Child render');
return <div>{value}</div>;
}
const MemoChild = React.memo(Child);
function Parent() {
const [count, setCount] = useState(0);
console.log('Parent render');
return (
<>
<MemoChild value="static" />
<button onClick={() => setCount(c => c + 1)}>+</button>
</>
);
}What happens:
Parent render
Child render ← first render
Parent render ← after the click
(Child does not re-render)React.memo noticed that props.value did not change → it did not call the component.
If React.memo is not specified
Then every time the parent re-renders, all child components will be called again - even if their props did not change.
function Child({ value }) {
console.log('Child render');
return <div>{value}</div>;
}
function Parent() {
const [count, setCount] = useState(0);
return (
<>
<Child value="static" /> {/* will always re-render */}
<button onClick={() => setCount(c => c + 1)}>+</button>
</>
);
}Every button click triggers:
Parent render
Child render (an unnecessary render)How React.memo compares props
React does a shallow comparison:
- it compares primitives (
number,string,boolean) by value; - it compares objects/arrays/functions by reference.
Important
const data = { name: 'Tim' };
<MemoChild user={data} />Even if the object looks the same,
React will see a new reference to { name: 'Tim' } on every render,
and MemoChild will still re-render.
The solution is to memoize the object:
const data = useMemo(() => ({ name: 'Tim' }), []);
<MemoChild user={data} />Custom comparison function
You can pass a second argument - a function that decides itself whether a re-render is needed:
const MemoChild = React.memo(Child, (prevProps, nextProps) => {
// return true → props are the same → do not re-render
// return false → props changed → re-render
return prevProps.id === nextProps.id;
});This is usually used for more complex checks, but by default a shallow compare is enough.
When React.memo is useful
Use it if:
- The component often receives the same props;
- Its rendering is heavy (complex markup, calculations);
- It does not depend on the parent's state directly;
- You control the stability of references (
useCallback,useMemo).
When React.memo is not needed
Do not use it if:
- The component always receives new props (or context);
- The component is small and renders quickly;
- The optimization does not give a real benefit (shallow compare can be more expensive).
Summary: what it comes down to
What React.memo does | What happens without it |
|---|---|
| Compares props and skips a repeated render | The component re-renders on every render of the parent |
| Works only when props are unchanged | React calls the component again every time |
| Works shallowly (by references) | React does not do any optimizations |
Effective together with useCallback and useMemo | Unnecessary re-renders of child components |
Example of an optimized combination
const Child = React.memo(({ onClick, label }) => {
console.log('Child render');
return <button onClick={onClick}>{label}</button>;
});
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => console.log('click'), []);
console.log('Parent render');
return (
<>
<Child onClick={handleClick} label="Press me" />
<button onClick={() => setCount(c => c + 1)}>+</button>
</>
);
}Here:
Childis wrapped inReact.memo;handleClickis stabilized viauseCallback;- So
Childdoes not re-render whencountchanges.
In short
| Question | Answer |
|---|---|
What does React.memo() do? | It caches the render result of a function component and skips a repeated call if the props have not changed |
| How does it compare props? | Shallowly (shallow compare) |
| What if it is not specified? | The component re-renders every time the parent re-renders |
| When is it useful? | When props rarely change and the component is expensive |
| When is it not needed? | When the component is lightweight or always receives new props |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.