Skip to content
advanced

Optimizing Re-renders with React.memo and Custom Comparisons

Learn how to prevent unnecessary re-renders using React.memo, including writing a custom comparison function to control exactly when a component updates.

import React, { useState } from 'react';

interface UserProfileProps {
  name: string;
  email: string;
}

// TODO: Wrap this component to prevent unnecessary re-renders
const UserProfile = __________(({ name, email }: UserProfileProps) => {
  console.log('UserProfile rendered');
  return (
    <div className="user-profile">
      <h2>{name}</h2>
      <p>{email}</p>
    </div>
  );
});

interface ExpensiveDisplayProps {
  data: {
    id: number;
    value: string;
  };
}

// TODO: Wrap this component with a custom comparison function
// It should only re-render when the data.id changes
const ExpensiveDisplay = __________(
  ({ data }: ExpensiveDisplayProps) => {
    console.log('ExpensiveDisplay rendered');
    // Simulate expensive calculation
    const processedValue = data.value.toUpperCase();
    return (
      <div className="expensive-display">
        <p>ID: {data.id}</p>
        <p>Value: {processedValue}</p>
      </div>
    );
  },
  // Return true if props are equal (should NOT re-render)
  // Return false if props are different (should re-render)
  __________...
);

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

  return (
    <div className="app">
      <UserProfile name="John Doe" email="john@example.com" />
      
      <div className="counter">
        <p>Count: {count}</p>
        <button onClick={() => setCount(count + 1)}>Increment</button>
      </div>

      <ExpensiveDisplay data={{ id: 1, value: dataValue }} />
      <button onClick={() => setDataValue(dataValue + '!')}>
        Change Value (should NOT re-render ExpensiveDisplay)
      </button>
    </div>
  );
}
0/3 filled tab moves · Ctrl+↵ submits · Ctrl+Shift+↵ runsstarter code