0
0
ReactHow-ToBeginner · 4 min read

How to Use React.memo for Performance Optimization

Use React.memo to wrap a functional component so React skips re-rendering it when its props have not changed. This improves performance by avoiding unnecessary updates for components with stable props.
📐

Syntax

React.memo is a higher-order component that takes a component and returns a memoized version of it. It only re-renders the component if its props change.

Basic syntax:

  • React.memo(Component): Wraps the component.
  • Component: Your functional component.
  • Optional second argument: a function to customize prop comparison.
javascript
const MemoizedComponent = React.memo(Component);

// With custom comparison
const MemoizedComponent = React.memo(Component, (prevProps, nextProps) => {
  // return true if props are equal (skip render)
  // return false if props changed (re-render)
});
💻

Example

This example shows a parent component rendering a child wrapped with React.memo. The child only re-renders when its count prop changes, even if the parent re-renders for other reasons.

javascript
import React, { useState } from 'react';

const Child = React.memo(({ count }) => {
  console.log('Child rendered');
  return <div>Count: {count}</div>;
});

export default function App() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  return (
    <div>
      <Child count={count} />
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
        placeholder="Type here"
      />
    </div>
  );
}
Output
When you type in the input, 'Child rendered' does NOT log because Child does not re-render. When you click 'Increment Count', 'Child rendered' logs because count changed.
⚠️

Common Pitfalls

Common mistakes when using React.memo include:

  • Wrapping components that always receive new props (like new objects or functions) causing memo to fail.
  • Not using a custom comparison function when props are complex objects.
  • Using React.memo on components that are cheap to render, which adds unnecessary overhead.

Always ensure props are stable or use useCallback and useMemo to keep props referentially equal.

javascript
import React, { useState, useCallback } from 'react';

const Child = React.memo(({ onClick }) => {
  console.log('Child rendered');
  return <button onClick={onClick}>Click me</button>;
});

export default function App() {
  const [count, setCount] = useState(0);

  // Wrong: new function created every render, memo fails
  // const handleClick = () => setCount(c => c + 1);

  // Right: useCallback keeps function stable
  const handleClick = useCallback(() => setCount(c => c + 1), []);

  return <Child onClick={handleClick} />;
}
Output
Without useCallback, 'Child rendered' logs every render. With useCallback, 'Child rendered' logs only once unless dependencies change.
📊

Quick Reference

  • Use React.memo to wrap functional components to skip re-renders when props are unchanged.
  • Use useCallback and useMemo to keep props stable and help memo work effectively.
  • React.memo only shallowly compares props, so use a custom comparison function for deep checks.
  • Don't overuse React.memo on simple or fast-rendering components.

Key Takeaways

Wrap functional components with React.memo to prevent unnecessary re-renders when props don't change.
React.memo does a shallow prop comparison; use a custom comparator for complex props.
Keep props stable using useCallback and useMemo to maximize React.memo benefits.
Avoid using React.memo on components that render quickly or rarely re-render.
React.memo improves performance by reducing rendering work but adds slight overhead.