React 16 업그레이드 후 Error Boundary 적용기
배경
회사 프로젝트를 React 15.6에서 16.0으로 업그레이드했다. 가장 눈에 띄는 변화는 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-page">
<h1>문제가 발생했습니다</h1>
<button onClick={() => window.location.reload()}>새로고침</button>
</div>;
}
return this.props.children;
}
}
주요 라우트마다 Error Boundary를 배치했다. 특히 써드파티 라이브러리를 사용하는 차트 컴포넌트 주변에 적용하니 효과가 좋았다.
<ErrorBoundary>
<ChartComponent data={chartData} />
</ErrorBoundary>
주의사항
Error Boundary는 이벤트 핸들러 내부의 에러는 잡지 못한다. 비동기 코드나 이벤트 핸들러는 여전히 try-catch가 필요하다.
handleClick = async () => {
try {
await fetchData();
} catch (error) {
this.setState({ error });
}
}
결과
프로덕션에서 전체 앱이 죽는 케이스가 확실히 줄었다. Sentry와 연동해서 에러 로그를 수집하니 사용자가 겪는 문제를 더 빨리 파악할 수 있게 되었다.