Explore Blogs
Optimizing react performance: Understanding React.memo and useMemo

Optimizing performance is essential for a smooth user experience. Two key techniques for this are React.memo and useMemo. While both enhance performance, they work differently and are used in various contexts.
In the world of React development, performance optimization is a critical aspect that can significantly enhance the user experience. Two powerful techniques in the React arsenal for achieving this are React.memo and useMemo. While both serve to optimize performance, they do so in different ways and are used in different contexts. Let's dive into what each of these techniques does, how they work, and when to use them.
What is React.memo?
React.memo is a higher-order component (HOC) that helps optimize the rendering of functional components. Its primary function is to memoize the rendered output of a component, which means it stores the output and reuses it if the props haven't changed. This prevents unnecessary re-renders and can greatly improve performance, especially in complex applications.
How React.memo works
When you wrap a functional component with React.memo, React performs a shallow comparison of the component's props. If the props are the same as the previous render, React skips re-rendering the component and reuses the last rendered output.
Syntax
Here's a simple example of how to use React.memo:
const MyComponent = ({ data }) => {
console.log('MyComponent rendered');
return <div>{data}</div>;
};
const MemoizedComponent = React.memo(MyComponent);In this example, MemoizedComponent is the optimized version of MyComponent. It will only re-render if the data prop changes.
Custom comparison
Sometimes, the default shallow comparison might not be sufficient. In such cases, you can provide a custom comparison function as the second argument to React.memo:
const MemoizedComponent = React.memo(MyComponent, (prevProps, nextProps) => {
return prevProps.someProp === nextProps.someProp;
});This custom function allows you to have more control over when the component should re-render.
How it works
The custom comparison function should return a boolean value:
true: If the function returnstrue, it indicates that the previous props (prevProps) and the next props (nextProps) are considered equal. In this case, React will skip re-rendering the component and reuse the last rendered output.false: If the function returnsfalse, it indicates that the props have changed, and React will proceed to re-render the component.
Let's consider an example to illustrate this:
const MyComponent = ({ data, anotherProp }) => {
console.log('MyComponent rendered');
return <div>{data}</div>;
};
const MemoizedComponent = React.memo(MyComponent, (prevProps, nextProps) => {
return prevProps.data === nextProps.data;
});
const ParentComponent = () => {
const [data, setData] = useState('initial data');
const [anotherProp, setAnotherProp] = useState('some value');
return <MemoizedComponent data={data} anotherProp={anotherProp} />;
};In this example:
- The custom comparison function checks if
prevProps.datais equal tonextProps.data. - If
datahas not changed, the function returnstrue, andMemoizedComponentwill not re-render. - If
datahas changed, the function returnsfalse, andMemoizedComponentwill re-render.
What happens when it returns true?
When the custom comparison function returns true:
- Rendering skipped: React skips the rendering process for the component. This means the component's render method is not called, and no new output is generated.
- Performance optimization: By skipping the render, React avoids unnecessary computations and DOM updates, which can improve the performance of your application.
- Reuse of previous output: The component reuses the output from the previous render. This is particularly useful for components that are expensive to render or have complex rendering logic.
What happens when it returns false?
When the custom comparison function returns false:
- Rendering triggered: React proceeds to call the component's render method, generating new output.
- DOM updates: The new output is compared with the previous output, and any necessary DOM updates are applied.
- Potential performance impact: If the component is expensive to render, this can have a performance impact. Therefore, it's important to use
React.memojudiciously and ensure that the custom comparison function is efficient.
The custom comparison function in React.memo gives you fine-grained control over when a component should re-render. By returning true when the props are considered equal, you can optimize performance by skipping unnecessary renders. Conversely, returning false triggers a re-render, ensuring that the component stays up-to-date with the latest props. Understanding how to use this feature effectively can help you build more efficient and performant React applications.
What is useMemo?
useMemo is a hook that memoizes the result of a function. It ensures that the function is only re-executed when its dependencies change. This is particularly useful for optimizing expensive calculations or stabilizing references to objects or functions.
How useMemo works
useMemo takes a function and an array of dependencies. The function is only re-executed when one of the dependencies changes. The memoized value is returned and remains the same as long as the dependencies do not change.
Syntax
Here's an example of how to use useMemo:
const MyComponent = ({ data }) => {
const memoizedValue = useMemo(() => expensiveComputation(data), [data]);
console.log('MyComponent rendered');
return <div>{memoizedValue}</div>;
};In this example, memoizedValue is the result of expensiveComputation(data). This computation is only re-executed when data changes.
Use cases
useMemo is commonly used to:
- Optimize performance: Avoid expensive calculations on every render.
- Stabilize references: Ensure that the reference to a value or function remains the same between renders, which can be important when passing props to child components.
Key differences
While both React.memo and useMemo serve to optimize performance, they do so in different ways:
Scope:
React.memomemoizes the rendered output of a component.useMemomemoizes the result of a function within a component.
Usage Context:
React.memois applied to a component as a whole.useMemois used within a component to optimize specific calculations or references.
Dependencies:
React.memorelies on prop comparisons to determine if a component should re-render.useMemorelies on an explicit array of dependencies to determine if the memoized value should be recomputed.
Customization:
React.memoallows for a custom comparison function.useMemodoes not support custom comparison functions; it strictly relies on the dependencies array.
Example comparison
Using React.memo
const MyComponent = ({ data }) => {
console.log('MyComponent rendered');
return <div>{data}</div>;
};
const MemoizedComponent = React.memo(MyComponent);
const ParentComponent = () => {
const [data, setData] = useState('initial data');
return <MemoizedComponent data={data} />;
};In this example, MemoizedComponent will only re-render if data changes.
Using useMemo
const MyComponent = ({ data }) => {
const memoizedValue = useMemo(() => expensiveComputation(data), [data]);
console.log('MyComponent rendered');
return <div>{memoizedValue}</div>;
};
const ParentComponent = () => {
const [data, setData] = useState('initial data');
return <MyComponent data={data} />;
};In this example, expensiveComputation(data) is only re-executed when data changes.
Conclusion
Both React.memo and useMemo are powerful techniques for optimizing performance in React applications. React.memo is used to memoize the rendered output of a component based on prop comparisons, while useMemo is used to memoize the result of a function within a component based on dependencies. Understanding when and how to use each of these techniques can help you build more efficient and performant React applications.