React Error Boundary로 구현하는 선언적 에러 처리

kiwon kim·2025년 1월 18일

Frontend

목록 보기
17/30
post-thumbnail

React 애플리케이션을 개발하다 보면 다양한 에러 상황에 마주치게 됩니다. 네트워크 오류, 데이터 형식 오류, 잘못된 상태 업데이트 등 예상치 못한 에러들이 발생할 수 있죠. 이런 에러들을 어떻게 하면 효과적으로 처리할 수 있을까요? 오늘은 React의 Error Boundary 기능을 활용한 선언적 에러 처리 방법에 대해 알아보겠습니다.

Error Boundary란?

Error Boundary는 React 16에서 도입된 기능으로, 하위 컴포넌트 트리에서 발생하는 JavaScript 에러를 캐치하고, 에러 상황에 대한 대체 UI를 보여줄 수 있게 해주는 React 컴포넌트입니다. 일종의 "JavaScript의 catch {}" 구문과 비슷한 역할을 하지만, 클래스 컴포넌트에서만 사용할 수 있다는 제한이 있었습니다.

하지만 현재는 react-error-boundary 라이브러리를 통해 함수형 컴포넌트에서도 쉽게 Error Boundary를 사용할 수 있습니다.

실전 예제로 알아보는 Error Boundary 구현

아래 예제를 통해 Error Boundary를 어떻게 구현하고 활용할 수 있는지 살펴보겠습니다.

"use client";

import { useEffect } from "react";
import { ErrorBoundary } from "react-error-boundary";
import { useNavigate } from "react-router-dom";

// Fallback 컴포넌트 타입 정의
interface FallbackProps {
  error?: Error;
  resetError?: () => void;
}

// 에러 발생 시 보여줄 Fallback 컴포넌트
const ErrorFallback: React.FC<FallbackProps> = ({ error, resetError }) => {
  const navigate = useNavigate();
  
  useEffect(() => {
    console.log("ErrorFallback rendered");
    resetError?.();
    navigate("/user");
  }, [navigate, resetError]);

  return <></>;
};

// 테스트를 위한 에러 발생 컴포넌트
const YourComponent: React.FC = () => {
  const isError = true;

  if (isError) {
    throw new Error("에러 발생!");
  }
  return <div>GOOD</div>;
};

// Error Boundary 적용
const Page: React.FC = () => {
  return (
    <ErrorBoundary fallback={<ErrorFallback />}>
      <YourComponent />
    </ErrorBoundary>
  );
};

코드 분석

1. ErrorBoundary 컴포넌트 설정

import { ErrorBoundary } from "react-error-boundary";

react-error-boundary 라이브러리에서 제공하는 ErrorBoundary 컴포넌트를 임포트합니다. 이 컴포넌트는 내부적으로 에러를 캐치하고 관리하는 로직을 포함하고 있습니다.

2. Fallback 컴포넌트 구현

interface FallbackProps {
  error?: Error;
  resetError?: () => void;
}

const ErrorFallback: React.FC<FallbackProps> = ({ error, resetError }) => {
  const navigate = useNavigate();
  
  useEffect(() => {
    resetError?.();
    navigate("/user");
  }, [navigate, resetError]);

  return <></>;
};
  • FallbackProps 인터페이스를 통해 Fallback 컴포넌트가 받을 props의 타입을 정의합니다.
  • error: 발생한 에러 객체
  • resetError: 에러 상태를 초기화하는 함수
  • 에러 발생 시 자동으로 /user 경로로 리다이렉션하고, 에러 상태를 초기화합니다.

3. Error Boundary 적용

const Page: React.FC = () => {
  return (
    <ErrorBoundary fallback={<ErrorFallback />}>
      <YourComponent />
    </ErrorBoundary>
  );
};

ErrorBoundary 컴포넌트로 에러가 발생할 수 있는 컴포넌트를 감싸고, fallback prop으로 에러 발생 시 보여줄 컴포넌트를 지정합니다.

Error Boundary의 장점

  1. 선언적 에러 처리: try-catch 구문처럼 명령형이 아닌, React의 선언적인 방식으로 에러를 처리할 수 있습니다.

  2. 컴포넌트 단위의 에러 격리: 특정 컴포넌트에서 발생한 에러가 전체 애플리케이션을 중단시키지 않도록 막을 수 있습니다.

  3. 유연한 에러 복구 전략: Fallback UI를 통해 사용자에게 적절한 피드백을 제공하고, 다양한 복구 전략을 구현할 수 있습니다.

  4. 타입스크립트 지원: 타입 안정성을 갖춘 에러 처리 로직을 구현할 수 있습니다.

주의사항

  1. Error Boundary는 다음과 같은 에러는 캐치하지 않습니다:

    • 이벤트 핸들러 내부의 에러
    • 비동기 코드 (예: setTimeout, requestAnimationFrame)
    • 서버 사이드 렌더링
    • Error Boundary 자체에서 발생하는 에러
  2. 이러한 케이스들은 일반적인 try-catch 구문이나 다른 에러 처리 방식을 활용해야 합니다.

실제 활용 전략

  1. 계층적 에러 처리
const App = () => {
  return (
    <ErrorBoundary fallback={<GlobalErrorFallback />}>
      <Layout>
        <ErrorBoundary fallback={<PageErrorFallback />}>
          <Page />
        </ErrorBoundary>
      </Layout>
    </ErrorBoundary>
  );
};
  1. 에러 로깅 추가
const ErrorFallback = ({ error, resetError }) => {
  useEffect(() => {
    // 에러 로깅 서비스로 에러 정보 전송
    logError(error);
  }, [error]);
  
  return (
    <div>
      <h2>Something went wrong</h2>
      <button onClick={resetError}>Try again</button>
    </div>
  );
};

결론

Error Boundary는 React 애플리케이션에서 발생하는 에러를 우아하게 처리할 수 있게 해주는 강력한 도구입니다. 특히 react-error-boundary 라이브러리를 활용하면 함수형 컴포넌트에서도 쉽게 구현할 수 있습니다.

적절한 계층에 Error Boundary를 배치하고, 상황에 맞는 Fallback UI를 제공함으로써 더 나은 사용자 경험을 제공할 수 있습니다. 다만, Error Boundary가 처리할 수 없는 케이스들도 있으므로, 전체적인 에러 처리 전략의 일부로 활용하는 것이 바람직합니다.

profile
FOR_THE_BEST_DEVELOPER

0개의 댓글