오늘은 React ErrorBoundary공식 문서를 활용하여 프론트엔드에서 에러 핸들링을 하는 방식에 대해서 얘기해보겠습니다.
리액트에서는 ErrorBoundary
를 아래와 같이 설명하고 있습니다.
❗️Note
Error boundary는 다음과 같은 에러는 포착하지 않습니다.
- 이벤트 핸들러
- 비동기 코드
- 서버사이드 렌더링
- 자식에서가 아닌 에러 경계 자체에서 발생하는 에러
ErrorBoundary를 배치할 위치
⇒ ErrorBoundary의 세분화된 부분은 개발자에게 달려있습니다.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
리액트에서 ErrorBoundary
는 클래스 컴포넌트를 이용하고 있고 클래스 컴포넌트에 있는 생명주기 메서드인 getDerivedStateFromError
와 componentDidCatch
를 사용하고 있습니다.
getDerivedStateFromError
componentDidCatch
아래는 일반 컴포넌트로 사용하는 방법입니다.
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
위와 같이 MyWidget 컴포넌트를 ErrorBoundary로 감싸면 catch 구문과 유사하게 해당 컴포넌트에서 발생시킨 Error를 catch 합니다.
❗️ 단 , 에러 경계는 트리 내에서 하위에 존재하는 컴포넌트의 에러만을 포착합니다.
App
컴포넌트
import React, { useEffect, useState } from "react";
import ErrorBoundary from "./ErrorBoundary";
function App() {
const ErrorTest = () => {
const [error, setError] = useState(false);
useEffect(() => {
if (error) throw new Error("Boom!");
}, [error]);
return <button onClick={() => setError(true)}>에러 만들기</button>;
};
return (
<ErrorBoundary>
<ErrorTest />
</ErrorBoundary>
);
}
export default App;
ErrorBoudary
컴포넌트
import React, { ErrorInfo } from "react";
interface ErrorBoundaryProps {
children: React.ReactNode;
}
interface ErrorBoundaryState {
hasError: boolean;
}
export default class ErrorBoundary extends React.Component<
ErrorBoundaryProps,
ErrorBoundaryState
> {
constructor(props: ErrorBoundaryProps) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error: Error) {
return { hasError: true };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {}
render() {
if (this.state.hasError) {
return (
<div>
<h2>에러가 발생했습니다. 잠시 후 다시 시도해주세요.</h2>
<button
type="button"
onClick={() => this.setState({ hasError: false })}
>
다시 시도
</button>
</div>
);
}
return this.props.children;
}
}
⛔️ 위에 예제는 인위적으로 에러를 발생시키기 위해 App 컴포넌트의 코드가 어색할 수 있습니다!
위 예제를 통해 ErrorTest 컴포넌트에 에러 만들기 버튼을 클릭하면 ErrorTest를 감싸고 있는 ErrorBoundary에서 Error를 Catch 하는 것을 확인할 수 있습니다.
끝까지 읽어주셔서 감사합니다. 😃
다음 포스팅은 프론트엔드 에러 핸들링 2편을 통해 재사용 가능한 ErrorBoundary를 알아보겠습니다.