Streaming
- Streaming은 데이터를 한 번에 모두 받아오는 대신, 데이터의 일부를 먼저 전송하여 초기 렌더링 시간을 단축시키는 기법입니다.
- 서버 사이드 렌더링(SSR)과 결합하면, 사용자에게 첫 화면을 빠르게 보여주면서 점진적으로 콘텐츠를 채워 나갈 수 있습니다.
React Suspense
- React Suspense는 컴포넌트가 로딩 중일 때 “대기 상태”를 선언할 수 있게 해 주는 기능입니다.
- 데이터를 비동기적으로 불러오는 상황에서, 로딩 스피너나 플레이스홀더 UI를 쉽게 적용할 수 있습니다.
TypeScript 환경에서의 기본 설정
먼저, TypeScript와 React 환경을 설정합니다.
아래는 기본적인 프로젝트 초기화 예시입니다.
npx create-react-app my-streaming-app --template typescript
cd my-streaming-app
- 프로젝트가 생성되면, 필요한 라이브러리(예: react, react-dom)는 이미 포함되어 있으므로 추가 설정 없이 시작할 수 있습니다.
React Suspense를 활용한 Data Fetching
Suspense와 Lazy Loading
React에서는 React.lazy와 Suspense를 이용하여 코드 스플리팅과 지연 로딩을 쉽게 구현할 수 있습니다.
예를 들어, 다음과 같이 컴포넌트를 동적으로 불러올 수 있습니다.
// LazyLoadedComponent.tsx
import React from 'react';
const LazyLoadedComponent: React.FC = () => {
return <div>이 컴포넌트는 지연 로딩됩니다!</div>;
};
export default LazyLoadedComponent;
// App.tsx
import React, { Suspense } from 'react';
const LazyComponent = React.lazy(() => import('./LazyLoadedComponent'));
const App: React.FC = () => {
return (
<div>
<h1>React Suspense 예제</h1>
<Suspense fallback={<div>로딩 중...</div>}>
<LazyComponent />
</Suspense>
</div>
);
};
export default App;
- 위 코드에서 Suspense 컴포넌트의 fallback 프로퍼티는 Lazy Component가 로드되는 동안 보여줄 UI를 정의합니다.
Suspense를 통한Data Fetching
실제 API 데이터를 불러오는 예제를 작성해봅니다.
아래는 React Suspense와 커스텀 훅을 활용하여 데이터를 비동기적으로 로드하는 방식입니다.
// useData.ts
import { useState, useEffect } from 'react';
interface Data {
id: number;
message: string;
}
const fetchData = async (): Promise<Data> => {
// 실제 API 호출 대신 모의 데이터를 반환합니다.
return new Promise((resolve) => {
setTimeout(() => {
resolve({ id: 1, message: 'Hello from the API!' });
}, 2000);
});
};
export const useData = () => {
const [data, setData] = useState<Data | null>(null);
useEffect(() => {
fetchData().then(setData);
}, []);
return data;
};
// DataComponent.tsx
import React from 'react';
import { useData } from './useData';
const DataComponent: React.FC = () => {
const data = useData();
if (!data) {
// Suspense가 관리하는 부분이므로 이 조건은 실제로 렌더링되지 않습니다.
throw new Promise(() => {});
}
return <div>{data.message}</div>;
};
export default DataComponent;
// App.tsx (업데이트)
import React, { Suspense } from 'react';
import DataComponent from './DataComponent';
const App: React.FC = () => {
return (
<div>
<h1>React Suspense를 활용한 데이터 페칭</h1>
<Suspense fallback={<div>데이터를 불러오는 중...</div>}>
<DataComponent />
</Suspense>
</div>
);
};
export default App;
- 위 예제에서는 데이터가 준비되지 않은 상태에서 Suspense가 fallback UI를 렌더링하게 하고, 데이터가 준비되면 실제 컴포넌트를 보여줍니다.
Streaming과의 결합
React 18부터는 Streaming SSR을 지원하여, 서버에서 클라이언트로 HTML 스트림을 전송할 수 있습니다.
이를 통해 사용자는 페이지의 일부를 먼저 렌더링하여 빠른 피드백을 받을 수 있습니다.
Next.js 같은 프레임워크는 이미 이러한 기능을 내장하고 있으며, 이를 활용하면 React Suspense와 Streaming을 자연스럽게 통합할 수 있습니다.
Next.js에서 Streaming과 Suspense 활용 예제
// pages/index.tsx (Next.js 13+ 예제)
import React, { Suspense } from 'react';
const StreamingComponent = React.lazy(() => import('../components/StreamingComponent'));
export default function Home() {
return (
<div>
<h1>Streaming과 Suspense 예제</h1>
<Suspense fallback={<div>스트리밍 중...</div>}>
<StreamingComponent />
</Suspense>
</div>
);
}
- Next.js의 최신 버전은 서버 컴포넌트를 활용하여 Streaming과 Suspense를 보다 효율적으로 처리합니다.
- 서버에서 데이터를 준비해 클라이언트로 스트리밍하면서 Suspense로 로딩 상태를 관리하는 방식은 사용자 경험을 극대화할 수 있습니다.
'개발 공부 > React' 카테고리의 다른 글
| React Dynamic Route Segments (0) | 2025.03.03 |
|---|---|
| Next.js revalidatePath, redirect (0) | 2025.02.26 |
| Static과 Dynamic Rendering (0) | 2025.02.23 |
| React.ReactNode, ReactElement, ComponentProps, Ref (0) | 2025.01.31 |
| React.FC (0) | 2025.01.30 |