How to optimize React performance with React.memo

· Category: React

Short answer

React.memo prevents a functional component from re-rendering if its props have not changed. useMemo caches expensive computations, and useCallback caches function references.

How it works

By default, React re-renders a component whenever its parent re-renders. Wrapping a component in React.memo performs a shallow comparison of props and skips the render if they are equal.

Example

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

const ExpensiveList = memo(function ExpensiveList({ items, onSelect }) {
  return (
    <ul>
      {items.map((item) => (
        <li key={item.id} onClick={() => onSelect(item.id)}>{item.name}</li>
      ))}
    </ul>
  );
});

function Parent() {
  const [items, setItems] = useState([...]);
  const handleSelect = useCallback((id) => {
    console.log(id);
  }, []);

  return <ExpensiveList items={items} onSelect={handleSelect} />;
}

Tips

  • Do not memoize everything; the comparison itself has a cost.
  • Always pair React.memo with useCallback for function props, or the memoization is negated.
  • Profile first with React DevTools before adding memoization.