React로 개발을 하다 보면 ‘로딩’과 ‘에러’는 정말 피할 수 없는 친구들입니다.
처음엔 단순히 isLoading이나 isError 같은 조건문으로 해결하려고 하지만,
프로젝트가 커질수록 코드가 꼬이고 화면이 깜빡이는 현상도 생기죠.
저도 예전에 대시보드 페이지를 만들 때,
데이터가 많아지니까 로딩 상태 처리만으로도 코드가 한참 복잡해졌던 기억이 있습니다.
그때 처음 알게 된 개념이 바로 Suspense와 Error Boundary였습니다.
이걸 몰라서 한참 헤맸던 시절
React에서 데이터를 불러올 때 대부분 이렇게 시작합니다.
const { data, isLoading, isError } = useQuery(['user'], fetchUser);
이런 구조는 직관적이지만,
페이지 곳곳에서 로딩 상태를 처리해야 하다 보니 코드가 금방 지저분해집니다.
컴포넌트가 많아질수록 isLoading이 페이지 절반을 차지하는 일도 생깁니다.
그럴 때 “로딩 중일 땐 이 부분을 잠시 멈춰둘 수 없을까?”
이 생각에서 React 팀이 만든 게 바로 Suspense입니다.
Suspense — 데이터를 기다리는 가장 자연스러운 방법
Suspense는 이름 그대로 “잠깐 멈추는” 역할을 합니다.
컴포넌트가 데이터를 기다리는 동안,
React가 대신 지정해둔 ‘대기 화면’을 보여주는 방식입니다.
import { Suspense } from 'react';
function App() {
return (
<Suspense fallback={<div>로딩 중입니다...</div>}>
<UserProfile />
</Suspense>
);
}
이 코드의 핵심은 fallback입니다.
데이터가 아직 준비되지 않았다면,
React는 일단 UserProfile을 멈추고 fallback UI를 대신 렌더링합니다.
이걸 직접 써보면 신세계입니다.
로딩 여부를 조건문으로 관리하지 않아도 되고,
컴포넌트가 깔끔하게 유지됩니다.
한참 삽질하다 깨달은 부분 — Error Boundary는 Suspense의 짝꿍이다
Suspense가 “로딩 중”을 책임진다면,
Error Boundary는 “문제가 생겼을 때”를 담당합니다.
이걸 몰랐을 땐 로딩 처리는 완벽하게 했는데
서버가 죽으면 화면이 하얗게 비는 현상이 자주 생겼습니다.
콘솔엔 에러가 떠 있지만 사용자는 아무것도 볼 수 없었죠.
React에선 이런 상황을 막기 위해
ErrorBoundary 컴포넌트를 따로 만들어야 합니다.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return <h2>문제가 발생했습니다. 새로고침 후 다시 시도해주세요.</h2>;
}
return this.props.children;
}
}
이걸 Suspense와 함께 감싸면
앱이 훨씬 안정적으로 돌아갑니다.
<ErrorBoundary>
<Suspense fallback={<LoadingSpinner />}>
<UserProfile />
</Suspense>
</ErrorBoundary>
실무에서 써보며 느낀 점
Suspense와 ErrorBoundary를 도입하고 나서
로딩 중, 성공, 실패 세 가지 상태가 완전히 분리됐습니다.
예전에는 이렇게 if문으로 감싸던 코드를
if (isLoading) return <Loading />;
if (isError) return <Error />;
지금은 Suspense와 ErrorBoundary에 맡길 수 있게 됐습니다.
특히 React Query와 함께 쓰면
isLoading이나 isError 같은 변수를 거의 볼 일이 없습니다.
UI는 항상 “정상 상태”만 보여주고,
로딩이나 에러는 자연스럽게 상위 컴포넌트에서 처리됩니다.
이 패턴이 진짜 빛나는 순간
Suspense는 단순히 로딩을 예쁘게 만드는 용도가 아닙니다.
코드의 구조 자체를 단순화시키는 도구입니다.
특히 API 요청이 많은 프로젝트일수록
이 패턴의 효과가 분명히 느껴집니다.
저는 관리자 대시보드 프로젝트에서
React Query + Suspense 조합으로 코드를 완전히 갈아엎었는데,
기존에 중복된 로딩 처리 코드가 70% 이상 줄었습니다.
에러가 나도 앱이 멈추지 않고,
유저 입장에서는 “앱이 멈춘 게 아니라 잠깐 대기 중”으로 보이게 되죠.
다음 글에서는 폼을 다루는 쪽으로 넘어갑니다.
React Hook Form을 이용해서 “입력값 검증과 상태 관리”를 효율적으로 처리하는 방법을 정리해볼 예정입니다.
실제 서비스에서 사용자 입력을 다룰 때 꼭 필요한 부분입니다.
'frontend > react' 카테고리의 다른 글
| [React] React.js 실무 강좌 34. React Hook Form과 zod로 폼 검증 완성하기 (0) | 2025.11.11 |
|---|---|
| [React] React.js 실무 강좌 33. React Hook Form으로 폼 상태를 깔끔하게 관리하기 (0) | 2025.11.11 |
| [React] React.js 실무 강좌 31. React Router v6 완전 가이드 — 페이지 전환의 모든 것 (0) | 2025.11.11 |
| [React] React.js 강좌 30. useEffect 완전 정복 — 렌더링 이후에 일어나는 일들 (0) | 2025.11.11 |
| [React] React.js 강좌 29. React의 렌더링 흐름 깊이 이해하기 (0) | 2025.11.11 |