Memoize component

2 snippets in React

REReact

React.memo

RE · useMemo & useCallback
syntax
const MemoizedComponent = React.memo(Component);
// With custom comparison
const MemoizedComponent = React.memo(Component, (prevProps, nextProps) => {
  return prevProps.id === nextProps.id;
});
example
import { memo, useState, useCallback } from 'react';

const ExpensiveRow = memo(function ExpensiveRow({ item, onToggle }) {
  // This component only re-renders if item or onToggle change
  return (
    <tr onClick={() => onToggle(item.id)}>
      <td>{item.name}</td>
      <td>{item.value.toFixed(2)}</td>
    </tr>
  );
});

function DataTable({ rows }) {
  const [selected, setSelected] = useState(new Set());

  const handleToggle = useCallback((id) => {
    setSelected(prev => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  }, []);

  return (
    <table>
      <tbody>
        {rows.map(row => (
          <ExpensiveRow key={row.id} item={row} onToggle={handleToggle} />
        ))}
      </tbody>
    </table>
  );
}

Note React.memo does a shallow comparison of props. It only helps if the component re-renders with the same props frequently. Pair it with useCallback for function props and useMemo for object/array props.

React.memo for Component Memoization

RE · Performance
syntax
const Memoized = React.memo(Component);
// Re-renders only when props change (shallow comparison)
example
import { memo } from 'react';

const ChatMessage = memo(function ChatMessage({ author, text, timestamp }) {
  // This only re-renders when author, text, or timestamp change
  return (
    <div className="message">
      <strong>{author}</strong>
      <p>{text}</p>
      <time>{new Date(timestamp).toLocaleTimeString()}</time>
    </div>
  );
});

// Parent re-renders frequently (new messages arrive)
// but existing ChatMessage components skip re-rendering
function ChatFeed({ messages }) {
  return (
    <div>
      {messages.map(msg => (
        <ChatMessage
          key={msg.id}
          author={msg.author}
          text={msg.text}
          timestamp={msg.timestamp}
        />
      ))}
    </div>
  );
}

Note React.memo only does a shallow prop comparison. If you pass objects or functions that are recreated each render, memo has no effect. Pair with useMemo/useCallback for those props.