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

문제 상황

사용자 대시보드에서 특정 위젯이 API 응답 파싱 중 에러가 발생하면 전체 페이지가 빈 화면으로 렌더링되는 문제가 있었다. React 15에서는 컴포넌트 내부 에러를 잡아낼 방법이 마땅치 않았다.

React 16으로 업그레이드하면서 Error Boundary를 적용해봤다.

Error Boundary 구현

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

  componentDidCatch(error, info) {
    this.setState({ hasError: true });
    // 에러 로깅 서비스로 전송
    logErrorToService(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;
  }
}

적용

각 위젯을 Error Boundary로 감싸서 격리했다.

<Dashboard>
  <ErrorBoundary>
    <SalesWidget />
  </ErrorBoundary>
  <ErrorBoundary>
    <UserStatsWidget />
  </ErrorBoundary>
  <ErrorBoundary>
    <RecentActivityWidget />
  </ErrorBoundary>
</Dashboard>

이제 한 위젯에서 에러가 발생해도 다른 위젯들은 정상적으로 표시된다. Sentry와 연동해서 에러 로그도 수집하도록 설정했다.

주의사항

  • 이벤트 핸들러 내부 에러는 잡지 못한다 (try-catch 사용 필요)
  • 비동기 코드(setTimeout 등)는 별도 처리 필요
  • Error Boundary 자체의 에러는 잡을 수 없다

React 16의 다른 기능들(Fragments, Portals)도 유용해 보여서 점진적으로 적용해볼 예정이다.