React Error Boundary実践ガイド - エラーでもアプリを落とさない方法
問題
子コンポーネントの一つでランタイムエラーが発生すると、アプリ全体が白い画面になってしまいます。本番環境でこれが起きると大問題です。
解決方法
Error Boundaryクラスコンポーネントを作成してエラーを隔離します。
import { Component, ReactNode } from 'react';
interface Props {
fallback: ReactNode;
children: ReactNode;
}
interface State {
hasError: boolean;
}
class ErrorBoundary extends Component<Props, State> {
state: State = { hasError: false };
static getDerivedStateFromError(): State {
return { hasError: true };
}
componentDidCatch(error: Error, info: React.ErrorInfo) {
console.error('ErrorBoundary caught:', error, info);
// Sentryなどのエラートラッキングサービスに報告
}
render() {
if (this.state.hasError) {
return this.props.fallback;
}
return this.props.children;
}
}
エラーが発生する可能性のあるセクションを個別にラップします。
function App() {
return (
<div>
<Header />
<ErrorBoundary fallback={<p>このセクションを読み込めませんでした。</p>}>
<UserProfile />
</ErrorBoundary>
<ErrorBoundary fallback={<p>コメントを読み込めませんでした。</p>}>
<Comments />
</ErrorBoundary>
<Footer />
</div>
);
}
UserProfileでエラーが発生しても、Commentsやその他の部分は正常に動作します。
ポイント
- Error Boundaryはクラスコンポーネントでのみ作成可能です(関数コンポーネントには
getDerivedStateFromErrorに相当するものがありません) - エラーの範囲をできるだけ狭く設定することが重要です。アプリ全体を一つでラップするのではなく、セクション単位でラップしましょう
- Error Boundaryはレンダリング中のエラーのみキャッチします。イベントハンドラ内のエラーはキャッチしません