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를 보고 새로고침할 수 있게 됐다.