노트

use()로 Promise 읽기

use

프런트엔드#react · 연결된 개념 9개

쉽게 말하면

use()는 카페 진동벨처럼 '곧 나올 값'을 받아 두었다가 렌더 중에 꺼내 읽는 API예요. 아직 안 나왔으면 Suspense의 대기 화면을 보여 주고, 나오면 그 값으로 다시 그려요.

비유가 깨지는 곳 진동벨은 계산대에서 받아 와야 해요. 클라이언트 렌더 안에서 Promise를 새로 만들면 렌더마다 새 벨이 생겨 계속 기다리게 되니, Promise는 서버 컴포넌트나 캐시하는 라이브러리처럼 렌더 밖에서 와야 해요.

use()는 렌더 중에 Promise나 Context 같은 리소스의 값을 읽는 React 19 API(Application Programming Interface)다. Promise가 아직 pending이면 컴포넌트가 suspend되어 가장 가까운 Suspense의 fallback이 보이고, 끝나면 그 값으로 다시 렌더된다. reject되면 가장 가까운 에러 경계(Error Boundary)로 던져진다.

// 서버 컴포넌트: 요청을 시작만 하고 await하지 않는다
async function Page() {
  const commentsPromise = fetchComments()
  return (
    <Suspense fallback={<p>댓글 불러오는 중…</p>}>
      <Comments commentsPromise={commentsPromise} />
    </Suspense>
  )
}
 
// 클라이언트 컴포넌트
'use client'
function Comments({ commentsPromise }) {
  const comments = use(commentsPromise)
  return <ul>{comments.map(c => <li key={c.id}>{c.text}</li>)}</ul>
}
  • 왜 await하지 않고 넘기나: 서버가 느린 데이터까지 기다리면 화면 전체가 늦는다. 셸과 fallback을 먼저 보내고, 데이터는 준비되는 대로 스트림으로 흘린다(스트리밍 SSR). 넘어간 Promise는 페이로드에서 참조로 직렬화된다
  • 훅 규칙의 예외: 조건문·반복문 안에서도 호출할 수 있다(React의 규칙과 렌더 순수성). use(SomeContext)도 useContext와 달리 조건부로 부를 수 있다
  • 함정: 클라이언트 컴포넌트 렌더 안에서 use(fetchComments())처럼 Promise를 새로 만들면, 렌더마다 새 Promise가 생겨 계속 suspend되거나 매번 다시 요청한다. Promise는 렌더 밖(서버 컴포넌트, 캐시하는 라이브러리)에서 와야 한다. 렌더 중에 읽는 것은 괜찮지만, 비동기 작업을 렌더 중에 새로 시작하는 것이 위험하다

서버는 await로, 클라이언트는 use()로 읽는다. 쓰기는 서버 함수와 서버 액션가 맡는다. Promise 자체는 Promise.

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • useTransition

    useTransition은 특정 상태 업데이트를 "급하지 않음(transition)"으로 표시해, 그 렌더 중에도 입력 같은 긴급한 업데이트가 먼저 처리되게 하는 훅이다. [isPending, startTransition]을 반환한다.

  • 서버 렌더에서 훅이 하는 일

    서버 렌더(Server-Side Rendering, SSR)에서도 컴포넌트 함수는 실제로 호출되고, 그 안의 훅도 호출은 된다. 다만 서버에는 커밋(DOM 반영)이 없어서, 렌더 중 동기적으로 값을 계산하는 훅만 일하고 커밋 뒤에 도는 훅은 아무것도 하지 않는다. "이 훅은 클라이언트에서만 동작한다"는 말은 대개 "Effect 안의 일은 클라이언트에서만 일어난다"는 뜻이다.

  • useDeferredValue

    useDeferredValue(value)는 값의 "지연된 버전"을 돌려주는 훅이다. 값이 바뀌면 React는 먼저 이전 값으로 긴급한 부분을 렌더하고, 새 값으로의 렌더는 낮은 우선순위로 백그라운드에서 한다.

  • 부수 효과와 Effect

    부수 효과(Side Effect)는 함수가 값을 계산해 돌려주는 본업 외에 바깥 세계를 건드리는 모든 동작이다. React의 Effect(useEffect로 감싼 코드)는 그중에서도 렌더가 끝난 뒤 외부 시스템과 맞추려고 실행하는 부수 효과만 가리키는 좁은 이름이다. 즉 Effect는 부수 효과의 부분집합이다.

  • 이벤트 루프

    자바스크립트를 실행하는 하나의 스레드가 할 일을 큐에서 하나씩 꺼내 처리하는 반복 구조. JS 엔진 자체에는 타이머도 네트워크도 없고, 브라우저(또는 Node.js)가 이 루프를 돌리면서 콜백을 엔진에 넘겨준다.

보기 옵션