⚛️ React Q25 / 113

What is React.memo?

AI-Powered Answer ✓ Answered

React.memo is a higher-order component (HOC) provided by React that helps optimize functional components by preventing unnecessary re-renders when their props have not changed. It's similar to PureComponent for class components, but specifically for functional components.

What is React.memo?

React.memo is a performance optimization tool that memoizes the rendering of a functional component. If a functional component wrapped with React.memo receives the same props as its previous render, React will reuse the last rendered result instead of re-rendering the component. This can significantly reduce the number of renders in your application, leading to better performance.

It works by performing a shallow comparison of the component's props. If the props are shallowly equal, React skips rendering the component and reuses the previously rendered result. This comparison is the key mechanism behind its efficiency.

How to Use React.memo

You wrap your functional component with React.memo during its export or declaration, like this:

jsx
import React from 'react';

const MyComponent = ({ propA, propB }) => {
  console.log('MyComponent is rendering!');
  return (
    <div>
      <p>Prop A: {propA}</p>
      <p>Prop B: {propB}</p>
    </div>
  );
};

export default React.memo(MyComponent);

Custom Comparison Function

By default, React.memo performs a shallow comparison of props. However, you can provide an optional second argument to React.memo, which is a custom comparison function. This function receives the old props and new props, and it should return true if the props are equal (i.e., the component should NOT re-render) and false if they are different (i.e., the component SHOULD re-render).

jsx
import React from 'react';

const arePropsEqual = (prevProps, nextProps) => {
  // Only re-render if propA changes, ignore propB
  return prevProps.propA === nextProps.propA;
};

const MyCustomMemoComponent = ({ propA, propB }) => {
  console.log('MyCustomMemoComponent is rendering!');
  return (
    <div>
      <p>Prop A: {propA}</p>
      <p>Prop B: {propB}</p>
    </div>
  );
};

export default React.memo(MyCustomMemoComponent, arePropsEqual);

Important Note on Custom Comparison

The custom comparison function for React.memo is different from shouldComponentUpdate in class components. shouldComponentUpdate returns true if the component SHOULD update, whereas the React.memo comparison function returns true if the component should NOT update (i.e., props are equal and no re-render is needed).

When to Use React.memo

  • Pure functional components: Components that render the same output given the same props.
  • Components that render frequently: If a component re-renders often without its props changing.
  • Components with complex rendering logic: Where the cost of re-rendering is high.
  • Components that receive children as props: If the children themselves are stable or memoized.

When NOT to Use React.memo

  • Components that re-render rarely: The overhead of prop comparison might outweigh the benefits.
  • Components that almost always receive new props: If props frequently change, memoization offers little value.
  • Components with simple rendering logic: The performance gain might be negligible.
  • When state changes cause re-renders: React.memo only optimizes based on props; useState or useReducer changes still trigger re-renders.

Key Considerations

  • Shallow Comparison: Remember that the default comparison is shallow. If you pass complex objects or arrays as props, and their references change (even if their contents are the same), React.memo will still trigger a re-render. For such cases, useMemo, useCallback, or a custom comparison function are essential.
  • useCallback and useMemo: These hooks are often used in conjunction with React.memo. useCallback memoizes functions and useMemo memoizes values, ensuring that stable references are passed down to memoized children, preventing unnecessary re-renders.
  • Overhead: While React.memo can improve performance, it adds a small overhead for prop comparison. Use it judiciously where performance bottlenecks are identified, rather than applying it to every component.