React Suspense
TMTReact Suspense는 비동기 작업의 상태를 관리하고, 데이터 로드 중에 로딩 UI를 표시하거나, 컴포넌트를 대체하는 등의 작업을 도와주는 기능입니다. Suspense는 React의 concurrent rendering 모델의 일부로, 비동기 작업을 기다리는 동안 UI를 "멈추고" 특정 fallback UI를 보여주는 방식으로 동작합니다.
동작 방식 및 원리
-
비동기 작업의 감지
- React 컴포넌트에서 Suspense를 사용할 때, React는 컴포넌트가 비동기 데이터를 필요로 하는 경우 해당 비동기 작업을 "대기" 상태로 만듭니다.
- 이 작업은 React의 특별한
throw Promise
메커니즘을 통해 구현됩니다. 컴포넌트는 Promise를 "던지고", React는 이 Promise가 해결될 때까지 기다립니다.
-
fallback UI 표시
- Suspense 컴포넌트는
fallback
속성을 통해 데이터를 로드하거나 대기하는 동안 보여줄 임시 UI를 지정합니다. - 비동기 작업이 완료되면 React는 fallback UI를 제거하고 실제 UI를 렌더링합니다.
- Suspense 컴포넌트는
-
비동기 작업 완료 및 UI 업데이트
- 비동기 작업이 완료되면 React는 해당 Promise의 상태를 감지하고, UI를 다시 렌더링합니다.
예시
1. 기본 Suspense 사용
코드
import React, { Suspense } from 'react';
const LazyComponent = React.lazy(() => import('./MyComponent'));
function App() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</div>
);
}
설명
React.lazy
를 사용하여 동적으로 컴포넌트를 로드합니다.- 컴포넌트가 로드되는 동안
fallback={<div>Loading...</div>}
이 화면에 표시됩니다. - 로드가 완료되면 실제 컴포넌트가 렌더링됩니다.
2. 데이터 Fetching과 Suspense
React Suspense는 데이터 fetching 라이브러리(예: React Query, SWR)와 함께 사용할 수도 있지만, 직접 구현도 가능합니다.
Suspense와 비동기 데이터 패턴
function fetchData() {
const promise = fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json());
return {
read() {
if (!promise) {
throw promise;
}
return promise;
},
};
}
const resource = fetchData();
function Post() {
const post = resource.read();
return <div>{post.title}</div>;
}
function App() {
return (
<Suspense fallback={<div>Loading post...</div>}>
<Post />
</Suspense>
);
}
설명
fetchData
함수는 데이터를 가져오는 비동기 작업을 수행하고, 데이터를 읽는read()
메서드를 가진 객체를 반환합니다.Post
컴포넌트는 데이터를 읽으려 할 때read()
메서드를 호출합니다.- 이 과정에서 Promise가 완료되지 않았으면 React는 Promise를 "잡고", Suspense의
fallback
UI를 표시합니다.
- 이 과정에서 Promise가 완료되지 않았으면 React는 Promise를 "잡고", Suspense의
- 데이터가 로드되면 React가 다시 렌더링하여 실제 데이터를 보여줍니다.
3. Suspense와 Error Boundary
비동기 작업 중 에러가 발생할 수도 있으므로, Error Boundary와 함께 사용하는 것이 일반적입니다.
function ErrorFallback({ error }) {
return <div>Error: {error.message}</div>;
}
function App() {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</ErrorBoundary>
);
}
요약
- React Suspense는 컴포넌트가 비동기 작업을 기다리는 동안 UI 상태를 관리하는 도구입니다.
fallback
속성을 통해 로딩 중에 보여줄 UI를 설정할 수 있습니다.- Suspense는 Promise를 "던지는" 메커니즘을 통해 비동기 상태를 관리합니다.
- 데이터 fetching 라이브러리와 함께 사용하면 더욱 효율적입니다.
- Error Boundary와 조합하여 에러 처리를 보완할 수 있습니다.
이런 원리를 이해하면 React Suspense를 활용해 사용자 경험을 개선할 수 있습니다. 🚀