반응형
프론트엔드 개발에서 데이터 로딩 상태를 관리하는 것은 매우 중요한 부분입니다. 이 글에서는 전통적인 useEffect
를 이용한 방식과 React의 새로운 기능인 Suspense
를 활용한 방식을 비교해보겠습니다.
useEffect를 이용한 로딩 상태 관리
기본 구현 방식
function UserProfile() {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
setIsLoading(true);
const response = await fetch('/api/user');
const result = await response.json();
setData(result);
} catch (err) {
setError(err);
} finally {
setIsLoading(false);
}
};
fetchData();
}, []);
if (isLoading) return <LoadingSpinner />;
if (error) return <ErrorMessage error={error} />;
return <UserInfo data={data} />;
}
장점
- 직관적인 구현 방식
- 기존 React 지식으로 쉽게 이해 가능
- 세밀한 에러 처리 가능
단점
- 보일러플레이트 코드가 많음
- 여러 비동기 작업 시 복잡한 조건부 렌더링
- 로딩 상태 관리 로직이 컴포넌트와 강하게 결합
Suspense를 이용한 로딩 상태 관리
기본 구현 방식
// 데이터 페칭을 위한 리소스 생성
function createResource(asyncFn) {
let status = 'pending';
let result;
let suspender = asyncFn().then(
(data) => {
status = 'success';
result = data;
},
(error) => {
status = 'error';
result = error;
}
);
return {
read() {
if (status === 'pending') {
throw suspender;
} else if (status === 'error') {
throw result;
} else if (status === 'success') {
return result;
}
}
};
}
// 컴포넌트에서 사용
function UserProfile() {
const resource = useMemo(() => createResource(
() => fetch('/api/user').then(res => res.json())
), []);
return (
<Suspense fallback={<LoadingSpinner />}>
<UserInfo data={resource.read()} />
</Suspense>
);
}
장점
- 선언적인 로딩 상태 관리
- 컴포넌트 코드가 더 깔끔해짐
- 로딩 UI를 중앙에서 관리 가능
단점
- Promise 기반 비동기 작업만 지원
- 중첩된 Suspense 사용 시 복잡한 로딩 상태 관리
- 추가적인 리소스 관리 로직 필요
두 방식의 주요 차이점
1. 상태 관리 방식
- useEffect: 명령형(Imperative) 방식
- 로딩 상태를 직접 관리
- 조건부 렌더링으로 UI 제어
- Suspense: 선언형(Declarative) 방식
- 로딩 상태를 컴포넌트 외부에서 관리
- fallback UI로 자연스러운 전환
2. 코드 구조
- useEffect:
if (isLoading) return <LoadingSpinner />; return <ActualContent />;
- Suspense:
<Suspense fallback={<LoadingSpinner />}> <ActualContent /> </Suspense>
3. 사용 사례
- useEffect:
- 단순한 데이터 페칭
- 세밀한 에러 처리 필요
- 기존 코드베이스와의 통합
- Suspense:
- 여러 비동기 작업 동시 처리
- 코드 분할과 함께 사용
- 새로운 프로젝트 시작
실제 사용 시 고려사항
1. Suspense 사용 시 주의점
- 중첩된 Suspense 컴포넌트 사용 시 로딩 UI가 여러 번 표시될 수 있음
- 데이터 준비 시점이 다를 수 있어 비일관적인 UI 경험 발생 가능
- Promise 기반 작업만 지원하므로 추가 라이브러리 필요할 수 있음
2. useEffect 사용 시 주의점
- 여러 비동기 작업 시 복잡한 상태 관리 필요
- 컴포넌트가 언마운트된 후 상태 업데이트 시 메모리 누수 가능성
- 로딩 상태 관리 로직이 컴포넌트와 강하게 결합
결론
useEffect 선택 시기
- 기존 프로젝트 유지보수
- 세밀한 에러 처리 필요
- 단순한 데이터 페칭
Suspense 선택 시기
- 새로운 프로젝트 시작
- 여러 비동기 작업 동시 처리
- 코드 분할과 함께 사용
각 방식은 장단점이 있으므로, 프로젝트의 요구사항과 상황에 맞게 선택하는 것이 중요합니다. Suspense는 React의 미래를 대표하는 기능이지만, 아직 실험적 기능이므로 프로덕션 환경에서 사용 시 신중한 검토가 필요합니다.
참고 자료
반응형
'Frontend Development' 카테고리의 다른 글
React 컴포넌트 설계의 핵심: 재사용성과 유지보수성을 높이는 방법 (0) | 2025.05.29 |
---|---|
브라우저 저장소 API: localStorage vs sessionStorage vs Cookie 완벽 가이드 (0) | 2025.05.29 |
React 라이프사이클과 Next.js: 차이점 완벽 가이드 (4) | 2025.05.29 |
프론트엔드 상태 관리: Flux, Proxy, Atomic 패턴과 주요 라이브러리 비교 (4) | 2025.05.28 |
Shadow DOM 완전 정리: 웹 컴포넌트의 핵심 기술 (0) | 2025.05.28 |