개요
use
는 Promise나 context 등 "리소스"의 값을 읽어오는 React API입니다. Suspense 및 에러 경계와 연동되어, 비동기 데이터 로딩이나 context 값을 유연하게 처리할 수 있습니다.
const value = use(resource);
Reference
use(resource)
컴포넌트 또는 커스텀 훅 내부에서 Promise나 context 등 리소스의 값을 읽어옵니다.
- 파라미터
resource
: 값을 읽고자 하는 리소스(Promise 또는 context 등)
- 반환값
- 리소스에서 읽어온 값(Promise의 resolve 값, context의 현재 값 등)
Caveats(주의사항)
- 반드시 컴포넌트 또는 훅 내부에서만 호출해야 합니다.
- Promise를 사용할 때는 Suspense 및 에러 경계와 함께 사용해야 하며, rejected Promise는 에러 경계에서 처리해야 합니다.
- Server Component에서 데이터 패칭에는 async/await를 우선 사용하세요. use는 컴포넌트 전체를 다시 렌더링하지만, await는 해당 지점부터 렌더링을 재개합니다.
- Client Component에서 Promise를 생성하면 매 렌더마다 새 Promise가 생성되므로, Server Component에서 Promise를 만들어 prop으로 전달하는 것이 좋습니다.
- try-catch 블록 내에서 use를 호출할 수 없습니다. 에러 처리는 에러 경계 또는 Promise.catch로 해야 합니다.
사용법
context 값 읽기
import { use } from 'react';
function Button() {
const theme = use(ThemeContext);
// ...
}
- use는 useContext와 유사하지만, 조건문/반복문 등 어디서든 호출할 수 있습니다.
- context 값을 읽을 때는 가장 가까운 Provider의 값을 반환합니다.
function HorizontalRule({ show }) {
if (show) {
const theme = use(ThemeContext);
return <hr className={theme} />;
}
return false;
}
서버에서 클라이언트로 Promise 스트리밍
Server Component에서 Promise를 생성해 Client Component로 prop으로 전달하고, Client Component에서 use로 값을 읽을 수 있습니다.
// App(Server Component)
import { fetchMessage } from './lib.js';
import { Message } from './message.js';
export default function App() {
const messagePromise = fetchMessage();
return (
<Suspense fallback={<p>waiting for message...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
);
}
// message.js(Client Component)
'use client';
import { use } from 'react';
export function Message({ messagePromise }) {
const messageContent = use(messagePromise);
return <p>Here is the message: {messageContent}</p>;
}
- Suspense로 감싸면, Promise가 pending일 때 fallback이 표시되고, resolve되면 실제 값이 렌더링됩니다.
- Promise가 reject되면 가장 가까운 에러 경계(Error Boundary)에서 에러를 처리해야 합니다.
rejected Promise 처리
- 에러 경계로 감싸거나, Promise.catch로 대체 값을 반환할 수 있습니다.
import { ErrorBoundary } from 'react-error-boundary';
<ErrorBoundary fallback={<p>⚠️Something went wrong</p>}>
<Suspense fallback={<p>⌛Downloading message...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
</ErrorBoundary>
트러블슈팅
"Suspense Exception: This is not a real error!" 오류
- use를 컴포넌트/훅 외부에서 호출했거나, try-catch 블록 내에서 호출한 경우 발생합니다.
- 반드시 컴포넌트/훅 내부에서만 호출하고, 에러 처리는 에러 경계 또는 Promise.catch로 하세요.
참고 및 주의사항
- use는 조건문/반복문 등 어디서든 호출할 수 있습니다.
- context 사용에는 useContext보다 더 유연합니다.
- Server Component에서는 async/await를 우선 사용하고, Client Component에서는 Server에서 생성한 Promise를 prop으로 전달해 사용하세요.
- rejected Promise는 반드시 에러 경계 또는 catch로 처리하세요.
반응형