Avoid redundant child renders
A parent updates often while a child receives stable primitive or memoized props.
React 19+ · Function
memo wraps a component so React can skip parent-driven re-renders when its props are unchanged. It improves performance opportunistically, but does not guarantee that a component will never render.
Wrap a component with memo to obtain a component that can skip parent-driven re-renders when its props are unchanged. React compares props and may reuse the previous result, but memoization is only a performance optimization; state or context changes can still cause rendering.
memo(Component, arePropsEqual?)| Name | Type | Description |
|---|---|---|
Component | ComponentType | The component to wrap. It should accept props and return JSX or another renderable React result. |
arePropsEqual | (oldProps, newProps) => boolean | Optional function receiving previous props and next props; return true when the rendered output and behavior would be equivalent. |
A new React component that behaves like the supplied component, while allowing React to skip a parent-triggered render when props have not changed.
import { memo, useState } from 'react';
const Greeting = memo(function Greeting({ name }: { name: string }) {
console.log('Greeting rendered');
return <p>Hello, {name}</p>;
});
export default function App() {
const [count, setCount] = useState(0);
return (
<main>
<button onClick={() => setCount(count + 1)}>Count: {count}</button>
<Greeting name="Ada" />
</main>
);
}The memoized Greeting can skip rendering when App updates but its name prop remains unchanged.
A parent updates often while a child receives stable primitive or memoized props.
A list contains expensive rows whose inputs usually remain unchanged.
A component accepts a custom equality rule that accurately identifies equivalent output.
Profiling shows a specific child render is a performance bottleneck.
memo returns a new React component that behaves like the original while allowing React to skip a parent-driven re-render when props have not changed. It compares props using the default comparison unless a custom comparator is supplied.
Follow-up: When can a memoized component still render? Its own state or consumed context can change, and React may render it because memoization is not a guarantee.
arePropsEqual receives the previous and new props and should return true only when the component would produce the same output and behavior. Returning true incorrectly can make the component display stale data.
Follow-up: Why can a custom comparator be risky? It must account for every prop relevant to rendering and behavior; otherwise React may incorrectly skip an update.
memo is useful when a component re-renders frequently with unchanged props and rendering it is measurably expensive. It is less useful when props are always new references or the component is inexpensive to render.
Follow-up: What should be optimized first? Keep rendering pure and use profiling to identify expensive or frequently repeated work before adding memoization.
useMemouseCallbackcacheReact Compiler