React 16 RC에서 componentDidCatch로 에러 바운더리 구현하기
배경
프로덕션 환경에서 특정 컴포넌트에서 에러가 발생하면 전체 앱이 흰 화면으로 변하는 문제가 있었다. 사용자 입장에서는 최악의 경험이고, 에러 추적도 어려웠다.
React 16 RC 버전에서 Error Boundaries라는 개념이 추가되어 테스트 환경에 적용해봤다.
구현
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 <h1>문제가 발생했습니다. 새로고침해주세요.</h1>;
}
return this.props.children;
}
}
주요 컴포넌트를 감싸서 사용했다.
<ErrorBoundary>
<UserProfile />
</ErrorBoundary>
주의점
- 이벤트 핸들러 내부 에러는 캐치하지 못한다
- 비동기 코드(setTimeout 등)의 에러도 잡지 못한다
- ErrorBoundary 자체의 에러는 처리할 수 없다
이벤트 핸들러는 여전히 try-catch로 처리해야 했다.
결과
특정 영역에서 에러가 발생해도 앱 전체가 다운되지 않고, Sentry로 에러 정보를 수집할 수 있게 됐다. React 16 정식 릴리즈 전에 미리 준비해둘 수 있어서 좋았다.
Fiber 아키텍처 변경으로 성능 개선도 기대되는데, 정식 버전이 나오면 프로덕션에 적용할 계획이다.