React / Optimization / Performance

Optimizing React Performance with `useMemo`, `memo`, and `useCallback`

April 19, 20243 min read
Woman surrounded by photo snapshots with eyes closed thinking of her memories
Photo by Ian Dooley

In React, optimizing performance is crucial for maintaining a smooth user experience, especially as applications grow in complexity. To help with this, React provides tools like useMemo, memo, and useCallback. These tools offer ways to optimize calculations and component rendering, preventing unnecessary computations and re-renders. Understanding the differences between these tools is essential for writing efficient React applications.

1. useMemo

Purpose: useMemo is a hook that memoizes a value. It recalculates the value only when one of its dependencies changes, which is useful for avoiding expensive computations on every render.

When to Use: Use useMemo to compute derived data based on props or state, and to avoid recalculating that data unless the dependencies change. It's particularly useful for optimizing performance by preventing repeated heavy calculations.

Example:

const MyComponent = ({ value1, value2 }) => {
  const computedValue = useMemo(() => {
    // Perform a heavy computation
    return heavyComputation(value1, value2);
  }, [value1, value2]);

  return <div>{computedValue}</div>;
};

2. memo

Purpose: memo is a higher-order component (HOC) that memoizes a functional component. React skips rendering the component if its props are shallowly equal to the previous props.

When to Use: Use memo to prevent a functional component from re-rendering unless its props have changed. It's useful for components that receive complex objects as props and are used frequently or have expensive rendering.

Example:

const MyComponent = memo(({ children }) => {
  return <div>{children}</div>;
});

3. useCallback

Purpose: useCallback is a hook that memoizes a callback function. The function is recreated only when one of its dependencies changes, which is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders.

When to Use: Use useCallback to prevent functions from being recreated on every render unless their dependencies change. This is important when passing callbacks as props to components that are optimized with React.memo or React.PureComponent, as a new function reference would cause them to re-render.

Example:

const MyComponent = ({ onFetch }) => {
  const memoizedCallback = useCallback(() => {
    onFetch('data');
  }, [onFetch]);

  return <button onClick={memoizedCallback}>Fetch Data</button>;
};

Key Differences

  • Function vs. Value vs. Component: useCallback is used for functions, useMemo for values, and memo for components.
  • Usage Context: useMemo and useCallback are hooks and must be used inside functional components or custom hooks. In contrast, memo is a higher-order component that wraps a functional component.
  • Performance Optimization: While all three help in optimizing performance, their use cases are distinct. useMemo prevents expensive recalculations, useCallback prevents function recreation, and memo prevents unnecessary re-renders of a component.

By understanding and using these tools appropriately, you can significantly improve the performance of your React applications by reducing unnecessary computations and re-renders.


ReactuseMemomemouseCallback