if (!data) {
  throw fetch()
}
  1. 컴포넌트가 렌더링될 때, 비동기 작업(예: 데이터 패칭)이 시작됩니다. 이 작업은 일반적으로 promise를 반환합니다.
  2. 비동기 작업이 완료되지 않은 경우, 컴포넌트는 promise를 던집니다. 이는 JavaScript에서 예외를 던지는 것과 유사합니다. Suspense는 promise가 던져질 때 이를 캐치하고 fallback UI를 표시하는 역할을 합니다.
  3. React는 컴포넌트가 promise를 던졌을 때 이를 감지하고, Suspense 컴포넌트에서 이를 “캐치”합니다. Suspense는 이 promise가 해결될 때까지 대체 UI (fallback)를 렌더링합니다. Concurrent Mode에서는 React가 이 promise를 추적하고, 비동기 작업이 완료될 때까지 렌더링을 중단합니다.
  4. Promise가 해결되면(즉, 비동기 작업이 완료되면) React는 컴포넌트를 다시 렌더링합니다. Suspense는 현재 데이터 패칭 라이브러리(예: React Query, SWR)와 함께 사용되어 비동기 작업의 상태를 쉽게 관리할 수 있도록 도와줍니다.

#307

declarative Combobox = render ∘ query ∘ defer. Suspense가 query: Q→Promise⟨D⟩를 throw로 바꿔 동기 Q→D로 위장하니, 전체가 명령형 조율이 아니라 함수 합성이 된다.

상태공간 곱→합. manual은 Q × Results × loading × error 곱집합이라 loading∧error 같은 모순 셀이 타입상 실재 — flicker는 렌더가 그 셀을 지날 때의 증상. 선언적 합 타입(loading | error | success)은 모순을 구성 불가능하게 만들고, case 분기를 if/else가 아니라 트리(<Suspense> / <ErrorBoundary> / 본문)가 담당한다. (형식 닻: ui_exclusive — 모든 값은 정확히 한 case.)

manual의 곱집합 상태공간엔 모순 셀(loading∧error 등)이 물리적으로 존재 — 선언적 합 타입은 그걸 표현 불가능하게 좁히고, case 분기를 트리 형태(Suspense/ErrorBoundary/본문)가 담당

Effect lifting = 자유 변수가 트리의 형태로. loading/error가 render의 인자(자유 변수)에서 사라지고, 가장 가까운 경계(<Suspense>/<ErrorBoundary>)가 잡는 ambient effect로 들린다 — renderResults 하나만 받는다. 대수적 효과(algebraic effects)의 handler 구조와 같은 모양.


stale-while-revalidate(two clocks·isStale) 부분은 [[570]]로.

#575