01 · Concept

React 메모이제이션

React에서 불필요한 리렌더링을 방지하는 메모이제이션 기법을 학습합니다.

React.memo는 props가 변경되지 않으면 리렌더링을 건너뛰는 고차 컴포넌트입니다. useMemo는 값을, useCallback은 함수 참조를 메모이제이션합니다. React Compiler는 이러한 최적화를 자동으로 수행하는 차세대 도구입니다.

02 · Interactive Demo

리렌더링 카운터 — memo 적용 전후 비교

부모 컴포넌트가 리렌더링될 때 자식의 렌더링 여부를 확인하세요.

부모가 리렌더링되면 자식도 무조건 리렌더링됩니다.
function Parent() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <button onClick={() => setCount(c => c + 1)}>
        count: {count}
      </button>
      <Child name="Kim" />  {/* 매번 리렌더링! */}
    </div>
  );
}

function Child({ name }) {
  console.log('Child 렌더링');  // 매번 출력
  return <div>Hello {name}</div>;
}
Render Count
Parent
0
Child
0
03 · Code Example

코드 예시

실제 코드로 동작 원리를 확인하세요.

import { memo } from 'react';

// props가 변경되지 않으면 리렌더링 스킵
const ExpensiveList = memo(function ExpensiveList({ items }) {
  console.log('ExpensiveList 렌더링');
  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
});

// 커스텀 비교 함수
const DeepMemoChild = memo(
  function Child({ data }) {
    return <div>{data.value}</div>;
  },
  (prevProps, nextProps) => {
    // true 반환 → 리렌더링 스킵
    return prevProps.data.value === nextProps.data.value;
  }
);
04 · Interview Point

면접 핵심 질문

React.memo는 컴포넌트를 감싸서 props가 변경되지 않으면 리렌더링을 스킵하는 고차 컴포넌트입니다. 기본적으로 얕은 비교(shallow comparison)를 수행합니다.

한계: 객체나 배열 props는 매 렌더링마다 새 참조가 생성되므로 얕은 비교에서 항상 “변경됨”으로 판단됩니다. 이를 해결하려면 useMemo/useCallback으로 참조를 유지하거나 커스텀 비교 함수를 전달해야 합니다.
useMemo을 메모이제이션합니다 — 비용이 큰 계산 결과를 캐싱하여 의존성이 변경될 때만 재계산합니다.useCallback함수 참조를 메모이제이션합니다 — 의존성이 변경되지 않으면 동일한 함수 참조를 반환합니다.

사실 useCallback(fn, deps)useMemo(() => fn, deps)의 축약형입니다. 주로 React.memo로 감싼 자식 컴포넌트에 콜백을 전달할 때 사용합니다.
React Compiler는 빌드 타임에 코드를 분석하여 자동으로 메모이제이션을 삽입합니다. 개발자가 수동으로 memo, useMemo,useCallback을 작성할 필요가 없어집니다.

컴파일러는 React의 규칙(순수 함수, 불변성 등)을 따르는 코드를 감지하고, 값과 함수의 의존성을 분석하여 최적의 메모이제이션 코드를 자동 생성합니다. React 19부터 실험적으로 지원됩니다.