React 16 이전의 버전에서는 UI 일부분에 존재하는 자바스크립트 에러가 전체 애플리케이션을 중단시켰습니다.
이를 해결하기 위해 React 16에서는 Error Boundary라는 새로운 개념이 도입되었습니다.
하위 컴포넌트 트리의 어디에서든 자바스크립트 에러를 기록하며, 깨진 컴포넌트 트리 대신 Fallback UI를 보여주는 React 컴포넌트 입니다.
-> 전체 어플리케이션이 중단되고, 아무것도 없는 흰 화면 대신 Fallback UI가 렌더링 됩니다.
렌더링 도중 생명주기 메서드 및 그 아래있는 전체 트리에서 에러를 잡아냅니다.
Error Boundary는 자바스크립트의 try().catch()
구문과 유사하게 동작하지만 컴포넌트에 적용됩니다.
-> 다시말하면 오직 컴포넌트만이 에러 경계가 될 수 있습니다.
static getDerivedStateFromError()
는 하위의 자손 컴포넌트에서 오류가 발생했을 때 호출됩니다.
이 메서드는 매개변수로 오류를 전달받고, 갱신된 state 값을 반드시 반환해야 합니다.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// state를 갱신하여 다음 렌더링에서 대체 UI를 표시합니다.
// 갱신돤 state 값을 return 하는 것은 필수입니다.
return { hasError: true };
}
render() {
if (this.state.hasError) {
// 별도로 작성한 대체 UI를 렌더링할 수도 있습니다.
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
자손 컴포넌트에서 오류가 발생했을 때 호출되며, 2개의 매개변수를 전달받습니다.
1. error
- 발생한 오류
2. info
- 어떤 컴포넌트가 오류를 발생시켰는지에 대한 정보를 포함한 componentStack
키를 가지고 있는 객체
getDerivedStateFromError - render
단계에서 호출되므로, 부수효과를 발생시키면 안됩니다.
componentDidCatch - commit
단계에서 호출되므로 부수효과를 발생시켜도 됩니다. 부수효과란 오류 로그 기록등을 의미합니다.
componentDidCatch(error, info) {
// Example "componentStack":
// in ComponentThatThrows (created by App)
// in ErrorBoundary (created by App)
// in div (created by App)
// in App
logComponentStackToMyService(info.componentStack);
}
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// 다음 렌더링에서 폴백 UI가 보이도록 상태를 업데이트 합니다.
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// 에러 리포팅 서비스에 에러를 기록할 수도 있습니다.
logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
// 폴백 UI를 커스텀하여 렌더링할 수 있습니다.
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
Error Boundary는 다음과 같은 에러는 포착하지 않습니다.
React 공식문서에 따르면 getDerivedStateFromError
, componentDidCatch
생명주기에 해당하는 Hook은 아직 없지만, 곧 추가할 계획이라고 합니다.
FallbackComponent
Error가 발생하였을 때 보여지는 component 입니다.
'error', 'resetErrorBoundary' props를 가질 수 있습니다.
FallbackRender
inline으로 fallback UI를 넣고 싶을 때 사용합니다.
Fallback, FallbackRender, FallbackComponent 셋중 하나는 반드시 있어야 합니다!
React에서 Error Boundary는 다음과 같은 에러는 포착하지 않습니다.
따라서 react-error-boundary에서는 위의 경우에 발생하는 에러를 핸들링하기 위해 useErrorHandler를 제공합니다.