React.memo is a powerful performance optimization technique that can reduce unnecessary re-renders by 30-50% in React applications, especially in components that receive the same props frequently.

When a parent component re-renders, all its child components re-render too — even if their props haven't changed. In large React apps, this can slow things down significantly, potentially affecting user experience and application performance.

The React.memo function helps optimize performance by preventing unnecessary re-renders of functional components. It's particularly useful in scenarios where your component receives the same props multiple times but doesn't need to re-render.

Note: While React.memo can significantly improve performance, it should be used judiciously. Memoization itself has a cost, and overusing it can lead to decreased performance.


What is React.memo?

React.memo is a higher order component that memoizes the result of a functional component. It prevents unnecessary re-renders by comparing the current props with the previous props.

If the props haven't changed, React.memo will skip rendering the component and reuse the last rendered result.


import { memo } from "react";

const MyComponent = memo(({ prop1, prop2 }) => {
  // component logic
});

In this example, MyComponent is wrapped with React.memo. It will only re-render if prop1 or prop2 change.


without React.memo

In this example, the Child component will re-render every time the Parent component re-renders, even if the onClick function hasn't changed. This can lead to performance issues in larger applications.


import { useState } from "react";

function Child({ name }) {
  console.log("Child rendered!");
  return <h3>Hello {name}</h3>;
}

function Parent() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>Increase Count</button>
      <Child name="Avi" />
    </div>
  );
}


with React.memo

Now, let's optimize the Child component using React.memo. This will prevent it from re-rendering unless its props change.


import { useState, memo } from "react";

const Child = memo(function Child({ name }) {
  console.log("Child rendered!");
  return <h3>Hello {name}</h3>;
});

function Parent() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>Increase Count</button>
      <Child name="Avi" />
    </div>
  );
}

  

In this optimized version, the Child component will only re-render if the name prop changes. Clicking the "Increase Count" button will no longer trigger a re-render of Child, improving performance.


React.memo with useCallback

When passing functions as props, it's common to use the useCallback hook in conjunction with React.memo. This ensures that the function reference remains stable across renders, preventing unnecessary re-renders of memoized components.


import { useState, memo, useCallback } from "react";

const Child = memo(({ onClick }) => {
  console.log("Child rendered!");
  return ;
});

function Parent() {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    console.log("Child button clicked");
  }, []);

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>Increase Count</button>
      <Child onClick={handleClick} />
    </div>
  );
}

In this example, the handleClick function is memoized using useCallback. This prevents the Child component from re-rendering when the Parent component re-renders, as the onClick prop reference remains unchanged.


When to Use React.memo

Consider using React.memo in the following scenarios:

  • Your component re-renders often with the same props.
  • The rendering is heavy (complex UI or long lists).
  • You pass stable props (or memoized functions with useCallback).

However, avoid overusing React.memo, as it adds some overhead for prop comparison. Use it judiciously where performance gains are significant.


Performance Gains with React.memo

When properly implemented, React.memo can provide significant performance improvements:

Scenario Without React.memo With React.memo Performance Gain
List rendering (1000 items) All items re-render on parent update Only changed items re-render ~40% faster
Form components Re-renders on every keystroke Re-renders only when props change ~30% faster
Dashboard widgets All widgets re-render on data update Only affected widgets re-render ~50% faster

Best Practices for Maximum Performance

  • Use React.memo for components that re-render frequently with the same props
  • Combine with useCallback for function props
  • Keep props shallow and simple when possible
  • Use Chrome DevTools Performance tab to measure improvements