--- 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
{data.name}
; } }> ``` ```tsx // React 19 use() function User({ promise }: { promise: Promise }) { const user = use(promise); return
{user.name}
; } ``` ## 🤔 의사결정 기준 | 상황 | 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]]