React Suspense와 Concurrent Mode의 개념과 활용
React Suspense와 Concurrent Mode의 핵심 개념을 쉬운 예제와 코드로 설명하고, suspense 데이터 페칭 패턴 및 react suspense 사용법을 정리한 개요
목차
개요
React에서 비동기 처리와 렌더링 우선순위는 사용자 경험에 직접적인 영향을 준다. 이 글은 React Suspense와 Concurrent Mode 개념을 초보자도 이해하기 쉽게 설명한다. 또한 실무에서 자주 쓰이는 suspense 데이터 페칭 패턴과 react suspense 사용법을 코드 예제로 보여준다.
React Suspense란
Suspense는 렌더링 중 비동기 작업을 기다리는 경계를 만든다. 컴포넌트가 준비될 때까지 폴백 UI를 보여준다. 주로 코드 스플리팅과 데이터 로딩에 활용된다. Suspense는 UI가 깜빡이지 않도록 자연스럽게 대기 상태를 처리한다.
핵심 아이디어
- 비동기 작업을 컴포넌트 수준에서 감싼다.
- 대기 중 보여줄 폴백을 정의한다.
- 여러 Suspense 경계로 로딩 단위를 분리할 수 있다.
Concurrent Mode 개념
Concurrent Mode는 렌더링을 중단하고 재개할 수 있게 해준다. 우선순위가 높은 작업을 먼저 처리할 수 있다. 덕분에 인터랙션이 부드러워진다. 다만 일부 기능은 실험적이거나 특정 React 버전에서만 동작할 수 있다.
왜 필요한가
- 대규모 UI에서 응답성 향상
- 긴 작업을 나눠서 처리하며 프레임 유지를 돕는다
- 동시성으로 사용자 입력을 우선 처리
react suspense 사용법 — 기본 예제
가장 흔한 사용법은 코드 분할과 조합하는 것이다. lazy와 Suspense를 함께 쓴다.
import React, { Suspense, lazy } from 'react';
import { createRoot } from 'react-dom/client';
const App = lazy(() => import('./App'));
createRoot(document.getElementById('root')).render(
<Suspense fallback=<div>로딩 중...</div>>
<App />
</Suspense>
);
위 코드는 createRoot를 사용해 Concurrent 특성을 활성화할 수 있다. Suspense의 fallback은 로딩 동안 보여줄 UI다.
suspense 데이터 페칭 패턴
데이터 페칭에도 Suspense를 적용하면 로딩 상태 관리를 단순화할 수 있다. 대표 패턴은 promise를 래핑해 읽기 함수(read)를 제공하는 것이다.
function wrapPromise(promise) {
let status = 'pending';
let result;
const suspender = promise.then(
r => { status = 'success'; result = r; },
e => { status = 'error'; result = e; }
);
return {
read() {
if (status === 'pending') throw suspender;
if (status === 'error') throw result;
return result;
}
};
}
function fetchUser(id) {
const promise = fetch(`/api/user/${id}`).then(r => r.json());
return wrapPromise(promise);
}
// 사용 예
const resource = fetchUser(1);
function User() {
const user = resource.read();
return <div>{user.name}</div>;
}
컴포넌트에서 resource.read()를 호출하면 데이터가 준비되지 않았을 때 Suspense 경계가 캐치해 폴백을 표시한다. 이 방식은 로딩, 에러 처리 흐름을 자연스럽게 만든다.
실무 적용 시 고려사항
- Concurrent Mode는 모든 라이브러리와 호환되는 것은 아니다. 실험적 기능을 확인한다.
- 데이터 캐싱과 무효화 전략을 함께 설계해야 한다.
- 너무 넓은 Suspense 경계는 작은 로딩 블록의 이점을 없앤다. 경계를 적절히 나눈다.
- 서버 사이드 렌더링과의 통합은 추가 설정이 필요하다.
권장 패턴
- 네트워크 요청은 리소스 래퍼로 추상화한다.
- UI는 작은 Suspense 경계로 분리한다.
- 에러는 별도의 Error Boundary로 처리한다.
- 퍼포먼스 문제가 보이면 프로파일링으로 병목을 찾는다.
결론
React Suspense와 Concurrent Mode는 복잡한 비동기 UI를 더 부드럽게 만든다. 기본 개념을 이해하고 suspense 데이터 페칭 패턴과 react suspense 사용법을 적용하면 사용자 경험이 개선된다. 도입 전 호환성, 캐싱, 경계 설계를 검토하는 것이 중요하다.