| 자식 컴포넌트 트리 안에서 발생한 자바스크립트 에러를 잡아서, 로깅하고, fallback UI (에러가 발생한 컴포넌트 트리 대신 대체해서 보여줄 UI)를 보여주는 리액트 컴포넌트이다.
단,
(1) 이벤트 핸들러
(2) 비동기 코드 (setTimeout, requestAnimtionFrame 등)
(3) 서버사이드 렌더링
(4) 자식 컴포넌트들이 아니라, 에러 바운더리 자체에서 발생한 에러
들은 Error boundaries가 캐치해내지 못한다.
공식문서에서 ErrorBoundary는 클래스 컴포넌트로 작성되어 있다.
아래코드는 공식문서의 예시 코드에 TS를 적용한 모습이다.
import { Component, PropsWithChildren, ReactNode } from 'react';
interface ErrorBoundaryProps extends PropsWithChildren {
fallback: ReactNode;
}
interface ErrorBoundaryState {
hasError: boolean;
}
export default class ErrorBoundary extends Component<
ErrorBoundaryProps,
ErrorBoundaryState
> {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(_: Error): ErrorBoundaryState {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error: Error, info: React.ErrorInfo): void {
// Example "componentStack":
// in ComponentThatThrows (created by App)
// in ErrorBoundary (created by App)
// in div (created by App)
// in App
console.error('Error caught by ErrorBoundary:', error);
console.error('Component stack:', info.componentStack);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return this.props.fallback;
}
return this.props.children;
}
}
ErrorBoundary 는 getDerivedStateFromError()
라는 컴포넌트생명주기를 활용하여, 하위 자식 컴포넌트 트리에서 발생한 애러를 캐치할 수 있다.
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
자식 컴포넌트에서 던져진(thrown)에러 이후에 이 생명주기 매서드가 발동된다. 그리고 그 에러가 매서드의 파라미터로 들어오게되고, 상태값인 hasError를 true로 변경하여 다음 렌더 때 fallbackUI를 보여주게 된다.
getDerivedStateFromError()
는 render
단계에서 호출되기에, 사이드 이펙트들이 허용되지 않는다.
UserManagement 컴포넌트 리팩토링 하는 과정에서 Error boundary를 사용해보았다.
단순히 공식문서만보고 아하, Error boundary를 쓰면 에러 발생시에 fallback UI를 렌더링해준대요
라고 믿기에는 뭔가 성에 차지 않는다.
개발 단계에서 Error boundary가 실제로 잘 동작하는지 여부를 테스트하기위해서는 어떤 방법들이 있을까?