01 · Concept

Suspense / Error Boundary

React에서 로딩과 에러 상태를 선언적으로 처리하는 두 가지 핵심 패턴입니다.

Suspense는 비동기 데이터 로딩 시 fallback UI를 선언적으로 표시합니다. Error Boundary는 렌더링 중 발생한 에러를 catch하여 앱 크래시를 방지합니다. React 19의 use() 훅과 함께 사용하면 Promise를 직접 읽으면서도 로딩/에러 상태를 자동으로 처리할 수 있습니다.

02 · Interactive Demo

Suspense / Error Boundary 흐름 시각화

각 패턴의 동작 흐름을 단계별로 시뮬레이션하여 확인하세요.

<Suspense fallback={<Spinner />}>
  <UserProfile />  {/* 데이터 로딩 중 → Spinner */}
</Suspense>

// React 19: use() 훅
function UserProfile() {
  const user = use(fetchUser());  // Promise throw
  return <h1>{user.name}</h1>;
}
Flow
1. Render
컴포넌트 렌더링 시작
2. Promise Throw
데이터 미준비 → Promise를 throw
3. Fallback
가장 가까운 Suspense의 fallback 표시
4. Resolve
Promise 해결 → 컴포넌트 재렌더
03 · Code Example

코드 예시

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

import { Suspense } from 'react';

// 데이터 페칭 라이브러리 (React Query, SWR 등)
function UserProfile() {
  const { data: user } = useSuspenseQuery({
    queryKey: ['user'],
    queryFn: fetchUser,
  });

  return <h1>{user.name}</h1>;
}

// Suspense로 로딩 상태 선언적 처리
function App() {
  return (
    <Suspense fallback={<Skeleton />}>
      <UserProfile />
    </Suspense>
  );
}

// 중첩 Suspense — 독립적 로딩 상태
function Dashboard() {
  return (
    <Suspense fallback={<PageSkeleton />}>
      <Header />
      <Suspense fallback={<ListSkeleton />}>
        <TodoList />
      </Suspense>
      <Suspense fallback={<ChartSkeleton />}>
        <Analytics />
      </Suspense>
    </Suspense>
  );
}
04 · Interview Point

면접 핵심 질문

Suspense는 React에서 비동기 작업의 로딩 상태를 선언적으로 처리하는 메커니즘입니다. 자식 컴포넌트가 아직 준비되지 않았을 때(Promise를 throw), 가장 가까운 Suspense의 fallback을 표시합니다. Promise가 resolve되면 자식 컴포넌트를 다시 렌더링합니다. 중첩하여 독립적인 로딩 상태를 구성할 수 있으며, React 18부터 서버 사이드 스트리밍 렌더링에도 활용됩니다.
Error Boundary는 자식 컴포넌트에서 발생한 렌더링 에러를 catch하여 앱 전체가 크래시되는 것을 방지합니다. getDerivedStateFromError componentDidCatch 라이프사이클 메서드가 필요한데, 이는 아직 함수형 컴포넌트에서 지원되지 않으므로 클래스 컴포넌트로 작성해야 합니다. 이벤트 핸들러, 비동기 코드, SSR의 에러는 catch하지 못하며, 오직 렌더링 단계의 에러만 처리합니다.
use()는 React 19에서 도입된 훅으로, Promise나 Context를 직접 읽을 수 있습니다. 기존 훅과 달리 조건문이나 반복문 안에서도 호출 가능합니다. Promise를 전달하면 Suspense와 연동되어 자동으로 로딩 상태를 처리하고, reject 시 Error Boundary로 에러가 전파됩니다. Context를 전달하면 useContext처럼 동작합니다.