본문 바로가기
기술의기록

React Suspense 완전 정복: 비동기 UI의 혁신적 해결책

by Jeremy Winchester 2025. 8. 9.
반응형

오늘은 React 개발자라면 꼭 알아야 할 React Suspense에 대해 이야기해보려고 해요. 혹시 비동기 데이터를 다룰 때마다 로딩 스피너와 에러 처리 코드로 컴포넌트가 복잡해져서 고민이신가요? 그렇다면 이 글이 정말 도움이 될 거예요!

React Suspense가 어떻게 동작하는지, 그리고 어떻게 우리의 코드를 더 깔끔하고 선언적으로 만들 수 있는지 함께 알아봐요.

🤔 React Suspense가 뭐죠?

React Suspense는 비동기 데이터에 의존하는 컴포넌트들을 위해 로딩과 에러 상태를 선언적으로 지정할 수 있게 해주는 메커니즘이에요.

기존에는 이렇게 했었죠:

 
 
javascript
function MyComponent() {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);
  
  // 복잡한 로딩 처리...
}

하지만 Suspense를 사용하면:

 
 
javascript
function MyComponent() {
  const data = use(dataPromise); // 끝!
  return <div>{data.name}</div>;
}

정말 깔끔하지 않나요?

🎯 Suspense의 놀라운 작동 원리

여기서 정말 신기한 부분이 나와요! Suspense는 Promise를 throw해서 작동한다는 거예요 😱

어떻게 이런 일이 가능할까요?

  1. 컴포넌트가 아직 준비되지 않은 데이터를 필요로 할 때, Promise를 throw합니다
  2. React가 이 Promise를 catch해서 렌더링을 일시정지시킵니다
  3. <Suspense>에서 제공한 fallback UI를 보여줍니다
  4. Promise가 resolve되면, React가 다시 렌더링을 시도합니다

이게 가능한 이유는 JavaScript에서 throw를 통해 함수를 동기적으로 멈출 수 있기 때문이에요. React가 이걸 활용해서 데이터가 준비될 때까지 렌더링을 "일시정지"시키는 거죠!

🔥 React 19의 use Hook

React 19부터 도입된 use Hook이 이 패턴의 핵심이에요. await 대신 use에 Promise를 전달하면:

 
 
javascript
function PhoneDetails() {
  const details = use(phoneDetailsPromise); // 마법이 일어나는 곳!
  return <div>{details.model}</div>;
}
  • Promise가 resolve되었다면: 값을 반환
  • Promise가 아직 pending이라면: Promise를 throw
  • Promise가 reject되었다면: Error Boundary가 처리

💡 실제 구현해보기

간단한 Suspense 데이터 페처를 만들어볼까요?

 
 
javascript
let userPromise;

function fetchUser() {
  userPromise = userPromise ?? fetch('/api/user').then(res => res.json());
  return userPromise;
}

function UserInfo() {
  const user = use(fetchUser());
  return <div>안녕하세요, {user.name}님!</div>;
}

function App() {
  return (
    <ErrorBoundary fallback={<div>앗, 뭔가 잘못됐어요!</div>}>
      <Suspense fallback={<div>사용자 정보 로딩중...</div>}>
        <UserInfo />
      </Suspense>
    </ErrorBoundary>
  );
}

보세요! UserInfo 컴포넌트에는 수동으로 작성한 로딩이나 에러 상태가 전혀 없어요. Suspense와 Error Boundary가 모든 걸 처리해줍니다.

✨ Suspense의 장점들

1. 선언적 (Declarative)

복잡한 상태 관리 없이 UI 의도를 명확하게 표현할 수 있어요.

2. 깔끔한 코드

로딩 스피너와 에러 처리 로직이 비즈니스 로직과 분리되어 코드가 훨씬 읽기 쉬워져요.

3. 재사용 가능

한 번 설정해두면 여러 컴포넌트에서 같은 패턴을 재사용할 수 있어요.

4. 조합 가능

여러 비동기 작업을 쉽게 조합하고 관리할 수 있어요.

🎊 마무리하며

React Suspense는 정말 혁신적인 기능이에요. "Promise를 throw한다"는 독특한 아이디어를 통해 비동기 UI를 훨씬 더 우아하게 처리할 수 있게 해주죠.

다음 프로젝트에서 Suspense를 사용해보세요. 코드가 얼마나 깔끔해지는지 직접 체험해보실 수 있을 거예요!

혹시 Suspense 사용하면서 궁금한 점이 있으시면 언제든 댓글로 질문해주세요. 함께 공부하며 성장해나가요! 💪

반응형