ErrorBoundaryを考える
Reactなどでエラーに直面する時、画面が真っ白になる場合がありました。
調べるとErrorBoundaryを実装すると(真っ白になるのを)防げるらしい
実装
import React, { ReactNode, ErrorInfo } from 'react';
type Props = {
children: ReactNode;
};
type State = {
hasError: boolean;
error: Error | null;
errorInfo: ErrorInfo | null;
};
export default class ErrorBoundary extends React.Component<Props, State> {
constructor(props: Props | Readonly<Props>) {
super(props);
this.state = {
hasError: false,
error: null,
errorInfo: null,
};
}
static getDerivedStateFromError(): { hasError: boolean } {
// 次のレンダリングでフォールバック UI が表示されるように状態を更新します。
return { hasError: true };
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
// エラー報告サービスにエラーを記録することもできます。
this.setState({ error, errorInfo });
}
render() {
if (this.state.hasError) {
console.log('JavaScript のエラー発生');
console.error(this.state.error?.message);
console.error(this.state.errorInfo?.componentStack);
// エラー時の表示
return <div></div>;
}
return this.props.children;
}
}
どういった動作なのか
static getDerivedStateFromError()
か componentDidCatch()
でエラーを検知してレンダリングを制御するらしい
ここまでは、いろんなサイトで書いてある
レンダリング
インターネットに例があったので実装してみた。
以下が実装結果
コンポーネントでのエラーの場合は、消えるようです。
次の画像がコンポーネントでの処理で起こったエラーです。
下記のコードを実装して5より上ならエラーが発生します。
const [count, setCount] = useState(0);
const setData = () => {
setCount(count + 1);
if (count > 5) throw new Error('エラーだよ');
};
1枚目のエラーで赤いエリアが消えたのは、レンダリング以前にエラーが発生しているから消えたのだと思います。
2枚目は、レンダリング事態には、問題がないため表示されます。しかし、カウントが5よりも上なので押すたびにエラーが発生します。
感想
コンポーネント自体が消えている場合、マウントされる前にエラーが起こっている。
再レンダリングされた際にコンポーネントが見えているのであれば処理系で何かエラーがあったんだと考えらばいいのかな?