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)도 유용해 보여서 점진적으로 적용해볼 예정이다.