use() 는 작은 hook 이지만 폭발 반경 큼. 컴포넌트가 promise 를 동기 값처럼 읽게 해주고 Suspense 가 wait 처리. 승리: success 경로에서 컴포넌트가 위에서 아래로 렌더; 통과시킬 로딩 state 없음.
모양
function MyComp({ promise }: { promise: Promise<T> }) {
const data = use(promise);
return <p>{data.value}</p>;
}
Promise pending 이면 use() suspend — React 가 가장 가까운 Suspense fallback 표시. Reject 면 use() throw — 가장 가까운 error boundary 잡음. Resolve 됐으면 use() 가 값 반환. 컴포넌트 body 는 success 케이스만 봄.
기본 규칙 — render 간 같은 promise
use() 가 promise 를 reference identity 로 인식. 매 render 마다 컴포넌트 안에 새 promise 만들면 use() 가 매번 다른 (여전히 pending) promise 봄, 매번 suspend, 무한 로딩 state.
고침: promise 를 컴포넌트 밖 에 생성 (또는 부모에서 만들어 prop 으로 전달, 또는 ref / context 에 캐시, 또는 캐싱 처리하는 TanStack Query 같은 라이브러리).
안정적 promise 출처 셋
- 부모 prop — 부모가 promise 생성 (한 번 또는 캐시된 팩토리로), 자식이 use() 로 소비.
- 모듈 레벨 상수 — one-off 부트스트래핑 데이터에 OK.
- 캐시된 팩토리 — React 의
cache헬퍼의cache((id: string) => fetch(id).then(j))같은 함수 (또는 본인의 Map 기반 memoization).
Context 와 use()
use() 가 Context 도 읽음 — useContext 와 달리 조건부 호출 가능. if (someCondition) { const value = use(MyCtx); } 가 use() 로는 합법, useContext 로는 불법. 일부 branch 가 필요 없는 Context 있을 때 편함.
use() 가 async 가 사는 자리의 책임을 이동. use() 전엔 각 컴포넌트가 자기 로딩 state 운반. use() 후엔 wait state 가 위쪽 Suspense 경계에, 컴포넌트는 값이 이미 거기 있는 것처럼 읽음. Leaf 가 단순해짐; 부모가 promise-생성 책임 짊어짐.