React 16의 Error Boundary로 컴포넌트 에러 처리하기

문제 상황

프로덕션 환경에서 특정 컴포넌트에서 에러가 발생하면 전체 화면이 하얗게 날아가는 문제가 있었다. 사용자가 특정 데이터를 조회할 때 간헐적으로 발생했는데, Sentry로 에러는 잡히지만 UX는 최악이었다.

Error Boundary 도입

React 16에서 componentDidCatch 라이프사이클이 추가되면서 컴포넌트 레벨에서 에러를 처리할 수 있게 됐다.

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    this.setState({ hasError: true });
    // Sentry.captureException(error);
    console.error('Error caught:', error, info);
  }

  render() {
    if (this.state.hasError) {
      return (
        <div className="error-fallback">
          <h2>일시적인 오류가 발생했습니다</h2>
          <button onClick={() => window.location.reload()}>
            새로고침
          </button>
        </div>
      );
    }
    return this.props.children;
  }
}

적용 방법

에러가 발생해도 전체 앱이 죽으면 안 되는 부분들을 ErrorBoundary로 감쌌다.

<ErrorBoundary>
  <UserDashboard />
</ErrorBoundary>

주요 페이지마다 개별적으로 적용해서 한 부분에서 에러가 나도 다른 부분은 정상 동작하도록 구성했다.

주의사항

  • 이벤트 핸들러 내부 에러는 잡지 못한다 (try-catch 사용 필요)
  • 비동기 코드(setTimeout 등)도 마찬가지
  • SSR 에러는 처리되지 않음

결과적으로 부분적인 에러로 전체 앱이 크래시되는 일이 크게 줄었다. 사용자는 에러 발생 시 fallback UI를 보고 새로고침할 수 있게 됐다.