에러 경계는 하위 컴포넌트 트리의 어디에서든 자바스크립트 에러를 기록하며 깨진 컴포넌트 트리 대신 폴백 UI를 보여주는 React 컴포넌트입니다. 에러 경계는 렌더링 도중 생명주기 메서드 및 그 아래에 있는 전체 트리에서 에러를 잡아냅니다. (by 리액트 공식 싸이트)
<ErrorBoundary>
<Compoents />
</ErrorBoundary>
의 형태로 에러 바운더리 하위에서 발생한 에러를 캐치하고, 에러 발생 시에는 보여줄 화면을 미리 지정해 둘 수 있다는 것입니다.
componentDidCatch
메서드에서는 두개의 매개변수 (error , info) 를 사용합니다. error는 에러의 내용을 알려주고, info는 에러가 발생한 위치를 알려줍니다.
getDerivedStateFromError
는 에러정보를 state에 저장해 화면에 나타내는 용도
이 두가지 메서드를 사용해야해서 따로 만들시 클래스컴포넌트로 만들어야한다.
간단한 예시
import React from 'react';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// 에러 상태 업데이트
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// 에러 로깅
console.error("Error caught by ErrorBoundary: ", error, errorInfo);
}
render() {
if (this.state.hasError) {
// 폴백 UI 렌더링
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
export default ErrorBoundary;
import React from 'react';
import ErrorBoundary from './ErrorBoundary';
import MyComponent from './MyComponent';
function App() {
return (
<div className="App">
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
</div>
);
}
export default App;
import React from 'react';
class MyComponent extends React.Component {
componentDidMount() {
throw new Error("This is a test error");
}
render() {
return <div>My Component</div>;
}
}
export default MyComponent;
위 예시에서 MyComponent
는 componentDidMount
에서 의도적으로 에러를 발생시킵니다. 이 에러는 ErrorBoundary
에서 잡아내고, 사용자에게 "Something went wrong." 메시지를 표시합니다.
위와 같은 방식으로 ErrorBoundary
를 활용하면 애플리케이션에서 발생하는 런타임 에러를 관리할 수 있습니다. 필요한 경우, componentDidCatch
메서드에서 에러를 외부 로깅 서비스에 전송하는 등의 추가 처리를 수행할 수도 있습니다.
추가로 궁금한 사항이 있으면 말씀해 주세요!
: 클래스형 errorBoundary와 거의 동일한 기능을 사용하면서도, 최근 리액트 개발의 주류인 함수형으로 errorBoundary를 작성할 수 있습니다
fallback렌더값을 props로 받고 있습니다. 클래스형에서 같은 작업을 해야했다면 별도로 재사용성을 높이기 위한 커스텀을 해줘야했거나 여러개의 에러 바운더리를 생성해야 했겠지만, 프롭스만으로 다르게 처리할 수 있게 되어 있습니다.
이를통해 프로젝트 내의 여러 부분의 특성에 맞게 에러 컴포넌트를 처리하거나, 페이지 단위보다 작은 파트를 단위로 에러 컴포넌트를 보여주는데 유용하게 처리할 수 있겠습니다
간단한 예시
import React from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import MyComponent from './MyComponent';
function ErrorFallback({ error, resetErrorBoundary }) {
return (
<div role="alert">
<p>Something went wrong:</p>
<pre>{error.message}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
);
}
function App() {
return (
<div className="App">
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={() => {
// 재시도 논리 (예: 컴포넌트 상태 리셋 또는 데이터 다시 로드)
console.log('Resetting...');
}}>
<MyComponent />
</ErrorBoundary>
</div>
);
}
export default App;
대표적인 서버상태관리 라이브러리인 react-query를 사용하는 경우, errorBoundary에서 에러 발생 후 reset 시 쿼리를 재시도하게 할 수 있습니다. 이 때 react-query의 useQueryErrorResetBoundary 훅을 사용하면, react-query의 QueryErrorResetBoundary 하위에 있는 쿼리 오류를 재설정 합니다.
react-query의 설정에 useErrorBoundary: true 속성을 세팅해줘야 오류 발생 시 errorBoundary에서 감지할 수 있다고 함.
Suspense
:React 애플리케이션에서 컴포넌트 트리가 로드되어야 하는 시점까지 지연되는 것들을 관리할 수 있도록 하는 기능입니다. 이는 특히 데이터 페칭 및 코드 스플리팅과 같은 비동기 작업을 처리하는 데 유용합니다
+추가로 useQuery에서 suspense 옵션을 true로 써주면 사용할 수 있음