React 로딩 상태 관리: useEffect vs Suspense

2025. 5. 29. 00:24·Frontend Development
반응형

프론트엔드 개발에서 데이터 로딩 상태를 관리하는 것은 매우 중요한 부분입니다. 이 글에서는 전통적인 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 사용 시 주의점

  • 여러 비동기 작업 시 복잡한 상태 관리 필요
  • 컴포넌트가 언마운트된 후 상태 업데이트 시 메모리 누수 가능성
  • 로딩 상태 관리 로직이 컴포넌트와 강하게 결합

결론

  1. useEffect 선택 시기

    • 기존 프로젝트 유지보수
    • 세밀한 에러 처리 필요
    • 단순한 데이터 페칭
  2. Suspense 선택 시기

    • 새로운 프로젝트 시작
    • 여러 비동기 작업 동시 처리
    • 코드 분할과 함께 사용

각 방식은 장단점이 있으므로, 프로젝트의 요구사항과 상황에 맞게 선택하는 것이 중요합니다. Suspense는 React의 미래를 대표하는 기능이지만, 아직 실험적 기능이므로 프로덕션 환경에서 사용 시 신중한 검토가 필요합니다.


참고 자료

  • React 공식 문서 - Suspense
  • React 공식 문서 - useEffect
  • React Suspense in Practice
반응형
저작자표시 비영리 변경금지 (새창열림)

'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
'Frontend Development' 카테고리의 다른 글
  • React 컴포넌트 설계의 핵심: 재사용성과 유지보수성을 높이는 방법
  • 브라우저 저장소 API: localStorage vs sessionStorage vs Cookie 완벽 가이드
  • React 라이프사이클과 Next.js: 차이점 완벽 가이드
  • 프론트엔드 상태 관리: Flux, Proxy, Atomic 패턴과 주요 라이브러리 비교
Kun Woo Kim
Kun Woo Kim
안녕하세요, 김건우입니다! 웹과 앱 개발에 열정적인 전문가로, React, TypeScript, Next.js, Node.js, Express, Flutter 등을 활용한 프로젝트를 다룹니다. 제 블로그에서는 개발 여정, 기술 분석, 실용적 코딩 팁을 공유합니다. 창의적인 솔루션을 실제로 적용하는 과정의 통찰도 나눌 예정이니, 궁금한 점이나 상담은 언제든 환영합니다.
  • Kun Woo Kim
    WhiteMouseDev
    김건우
  • 깃허브
    포트폴리오
    velog
  • 전체
    오늘
    어제
  • 공지사항

    • [인사말] 이제 티스토리에서도 만나요! WhiteMouse⋯
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 분류 전체보기 (100) N
      • Frontend Development (39) N
      • Backend Development (21) N
      • Algorithm (33) N
        • 백준 (11) N
        • 프로그래머스 (17)
        • 알고리즘 (5)
      • Infra (1)
      • 자료구조 (3)
  • 링크

    • Github
    • Portfolio
    • Velog
  • 인기 글

  • 태그

    tailwindcss
    frontend development
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Kun Woo Kim
React 로딩 상태 관리: useEffect vs Suspense
상단으로

티스토리툴바