react-error-boundary란?
https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary
https://ko.legacy.reactjs.org/docs/error-boundaries.html
공식문서에서는 여기에서 찾아볼 수 있습니다.
react-error-boundary 이야기를 하기 이전에 리액트 얘기를 안 할 수가 없는데
리액트에서 제시하는 에러바운더리는 에러의 경계를 정해주는 컴포넌트입니다.
과거에는 컴포넌트 내부의 자바스크립트 에러가 리액트의 상태를 훼손하고,
다음 렌더링에서 에러를 만들어냈지만
리액트 컴포넌트 내부에서 에러를 처리할 방법이 없어서 복구하는게 어려웠던 문제가 있었습니다.
이 문제를 해결해주면서 프로미스의 catch 메서드 혹은 try catch문을 통해
명령적으로 제어하던 에러 처리를 마치
Suspense와 같이 선언적으로 처리하도록 돕는 개념이라고 인식할 수 있습니다.
다만 약간의 문제가 있는데... 이 Error Boundary를 함수형으로 작성할 방법이 존재하지 않는다는 것입니다.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, info) {
// Example "componentStack":
// in ComponentThatThrows (created by App)
// in ErrorBoundary (created by App)
// in div (created by App)
// in App
logErrorToMyService(error, info.componentStack);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return this.props.fallback;
}
return this.props.children;
}
}
이런 형태의 클래스로밖에 작성할 수 없는 것이죠
하지만 react-error-boundary를 사용하면 이런 에러바운더리 구현없이
바로 에러바운더리를 사용할 수 있습니다.
설치 방법
npm install react-error-boundary
간단하게 install 해줍니다.
"use client";
import { ErrorBoundary } from "react-error-boundary";
<ErrorBoundary fallback={<div>Something went wrong</div>}>
<ExampleApplication />
</ErrorBoundary>
Suspense와 매우 유사한 사용법을 가지고있습니다.
fallback 내부에 에러상태일때 표시될 컴포넌트를 넣어줍니다.
그런데 그런 경우가 있습니다.
던져진 에러메시지를 기반으로 화면을 다르게 구성하고 싶은 경우
많지않나요?
"use client";
import { ErrorBoundary } from "react-error-boundary";
function fallbackRender({ error, resetErrorBoundary }) {
// Call resetErrorBoundary() to reset the error boundary and retry the render.
return (
<div role="alert">
<p>Something went wrong:</p>
<pre style={{ color: "red" }}>{error.message}</pre>
</div>
);
}
<ErrorBoundary
fallbackRender={fallbackRender}
onReset={(details) => {
// Reset the state of your app so the error doesn't happen again
}}
>
<ExampleApplication />
</ErrorBoundary>;
공식문서에서 제공해주는 사용례는 다음과 같습니다.
FallbackComponent prop의 내부에 들어가는 컴포넌트들은 error, resetErrorBoundary가 담긴 객체를
인수로 전달받게되는데요
이를 활용하여 에러페이지를 적절히 핸들링할 수 있습니다.
error에는 error 객체가 담겨있을 것이고
resetErrorboundary에는 next.js를 이용해보신 분이라면 익숙할 것 같은데 리셋함수가 들어있습니다.
가장 최근에 일어난 에러가 일어난 지점을 다시 시도해보는 함수에요
import { FallbackProps } from 'react-error-boundary';
import Button from '../atom/Button';
import Paragraph from '../atom/Paragraph';
import HeadingParagraph from '../atom/HeadingParagraph';
const ErrorFallback = ({ error, resetErrorBoundary }: FallbackProps) => {
return (
<div className=" flex flex-col items-center justify-center px-3 pt-52">
<HeadingParagraph variant={'darkgray'} size={'xl'} className="text-center">
{error.message}
</HeadingParagraph>
<Button onClick={() => resetErrorBoundary()}>reset</Button>
<Paragraph className=" mt-4">
<strong className=" text-sky-400">잠시</strong> 기다려주세요
</Paragraph>
</div>
);
};
export default ErrorFallback;
제 프로젝트에서는 위와같이 구성하여 Error Fallback을 사용해주었습니다.
<ErrorBoundary FallbackComponent={ErrorFallback}>
<Suspense fallback={<LoadingPage />}>
<RouterProvider router={router} />
<ReactQueryDevtools />
</Suspense>
</ErrorBoundary>
이제 ErrorBoundary로 감싸주고 FallbackComponent prop에
만들어둔 ErrorFallback 컴포넌트를 집어넣어주겠습니다.
이 외에도 다양한 사용례들이 깃허브에 잘 정리되어있습니다.
https://github.com/bvaughn/react-error-boundary
좀 더 심화된 유즈케이스들을 원하신다면 깃허브 쪽을 살펴보시기를 추천드립니다.
'react' 카테고리의 다른 글
리액트를 사용하는 이유는 무엇일까? (2) | 2023.08.04 |
---|---|
reactquery useQuery 자동 가져오기 막는 법 (0) | 2023.07.31 |
react-query의 onError는 Deprecated 되었다. (0) | 2023.07.12 |
react-query를 이용해 pagenation을 구현해보자(2) (2) | 2023.06.30 |
react-query를 이용해 pagenation을 구현해보자 (0) | 2023.06.29 |