react에서 제공하는 ErrorBoundary가 존재한다
생명주기 메서드 중 getDerivedStateFromError와 ComponentDidCatch를 정의하면 ErrorBoundary로 사용할 수 있다. ComponentDidCatch를 사용하여 에러 정보를 기록할 수 있다.
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;
}
}

위와 같은 사항을 포착하지 못한다.
그렇다. 위 ErrorBoundary의 한계에서 2번에 해당하는 내용이다. 비동기적 코드는 react-query, swr등의 비동기 통신 라이브러리를 사용해야 한다. 혹은, 직접 에러를 컴포넌트에서 동기적으로 던져주는 방법도 있다.
에러를 throw하는 방법을 공부해보기 위해, 직접 동기적으로 에러를 throw하는 로직을 작성해보자.
function Children() {
const [todos, setTodos] = useState([]);
const [error, setError] = useState(null);
useEffect(() => {
(async () => {
try {
const res = await axios.get(
"<https://jsonplaceholder.typicode.com/todos21231>"
);
setTodos(res.data);
} catch (e) {
setError(e);
}
})();
}, []);
if (error) {
throw error;
}
return click;
}
데이터를 fetch하는 곳에서 throw를 하는 것이 아니라, 바깥에서 에러를 던지는 것이다. 데이터 fetch하는 함수는 비동기적으로 실행되기 때문에, ErrorBoundary의 try-catch문 바깥에 있어서 포착하지 못한다. 동기적으로 실행되는 곳에서 throw를 해주면 이 throw문은 ErrorBoundary에서 포착하여 에러 화면을 보여줄 수 있다.
useError로 error를 throw하는 로직을 추상화하자그리고, 이러한 error에대한 로직을 커스텀 훅으로 만들었다.