---
id: react-suspense-for-data
title: React Suspense — 데이터 페칭 통합
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [react, suspense, data-fetching, vibe-coding]
tech_stack: { language: "TypeScript / React 18+", applicable_to: ["Web", "RSC"] }
applied_in: []
aliases: [Suspense boundary, concurrent rendering]
---

# React Suspense — 데이터 페칭 통합

> Suspense 는 "이 자식이 준비될 때까지 fallback 보여줘" 라는 선언적 경계. 프레임워크(Next/Remix) 또는 데이터 라이브러리(Relay/RSC/React Query 의 suspense 모드)와 함께 써야 의미.

## 📖 핵심 개념
- 컴포넌트가 promise 를 throw → Suspense 경계가 catch → fallback 렌더.
- 직접 promise throw 하지 마라. 라이브러리가 throw 처리.
- React 19 에서 use(promise) hook 가 정식.

## 💻 코드 패턴

```tsx
// React Query 의 suspense 모드
function User({ id }) {
  const { data } = useSuspenseQuery({ queryKey: ['user', id], queryFn: () => fetchUser(id) });
  return <div>{data.name}</div>;
}

<Suspense fallback={<Spinner />}>
  <User id={1} />
  <User id={2} />
</Suspense>
```

```tsx
// React 19 use()
function User({ promise }: { promise: Promise<User> }) {
  const user = use(promise);
  return <div>{user.name}</div>;
}
```

## 🤔 의사결정 기준
| 상황 | Suspense | 직접 isLoading state |
|---|---|---|
| 라이브러리 지원 (Next App Router, RSC, React Query suspense) | ✅ | — |
| 여러 페치를 한 fallback 으로 묶고 싶음 | ✅ | ❌ (복잡) |
| Streaming SSR | ✅ (필수) | ❌ |
| 단일 컴포넌트 단순 fetch + 라이브러리 없음 | ❌ | ✅ |

## ❌ 안티패턴
- **컴포넌트 안에서 직접 promise throw**: caching 없으면 무한 fetch. 라이브러리 사용.
- **Suspense 경계 안에서 useEffect fetch + setState**: Suspense 와 무관. 그냥 일반 패턴.
- **너무 좁은 fallback 경계 (각 글자마다)**: 복잡. 보통 화면 영역 단위.
- **error boundary 안 걸기**: Suspense 는 로딩만, 에러는 ErrorBoundary 별도.
- **Server Component 와 Client Component 혼동**: RSC 의 Suspense 는 streaming, Client Suspense 는 다른 경계.

## 🤖 LLM 활용 힌트
- React Query / SWR / Apollo / RSC 환경 명시 필수. 그에 따라 패턴 다름.
- "각 Suspense 경계에 ErrorBoundary 동반" 명시.

## 🔗 관련 문서
- [[React_Server_Components]]
- [[React_Error_Boundary]]
