Skip to main content

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

javascript
const MemoizedComponent = React.memo(MyComponent);

or directly:

javascript
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:

javascript
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:

javascript
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.

javascript
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:

javascript
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

javascript
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:

javascript
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:

javascript
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:

  1. The component often receives the same props;
  2. Its rendering is heavy (complex markup, calculations);
  3. It does not depend on the parent's state directly;
  4. 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 doesWhat happens without it
Compares props and skips a repeated renderThe component re-renders on every render of the parent
Works only when props are unchangedReact calls the component again every time
Works shallowly (by references)React does not do any optimizations
Effective together with useCallback and useMemoUnnecessary re-renders of child components

Example of an optimized combination

javascript
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:

  • Child is wrapped in React.memo;
  • handleClick is stabilized via useCallback;
  • So Child does not re-render when count changes.

In short

QuestionAnswer
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 ready
Premium

A concise answer to help you respond confidently on this topic during an interview.