こんにちは!今回は、Reactアプリケーションでエラーハンドリングを簡単に行えるライブラリ「react-error-boundary」のErrorBoundary
コンポーネントについて、初心者向けに詳しく解説します。
ErrorBoundaryとは?
ErrorBoundary
は、Reactアプリケーション内で発生するJavaScriptエラーをキャッチし、エラーによってクラッシュしたUIの代わりにフォールバックUI(エラーメッセージなど)を表示するためのコンポーネントです。
Reactには標準でエラー境界(Error Boundary)の機能がありますが、react-error-boundary
ライブラリを使用すると、より柔軟で強力なエラーハンドリングが可能になります。
基本的な使い方
まず、react-error-boundary
をインストールします。
npm install react-error-boundary
次に、ErrorBoundary
コンポーネントをインポートし、エラーをキャッチしたいコンポーネントをErrorBoundary
でラップします。
import React from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import MyComponent from './MyComponent';
function ErrorFallback({ error, resetErrorBoundary }) {
return (
<div role="alert">
<p>エラーが発生しました:</p>
<pre>{error.message}</pre>
<button onClick={resetErrorBoundary}>再試行</button>
</div>
);
}
function App() {
return (
<ErrorBoundary
FallbackComponent={ErrorFallback}
onReset={() => {
// リセット時の処理をここに記述
}}
>
<MyComponent />
</ErrorBoundary>
);
}
export default App;
説明
ErrorFallback
コンポーネント: エラー発生時に表示するフォールバックUIを定義します。error
オブジェクトからエラーメッセージを取得し、ユーザーに表示します。また、resetErrorBoundary
関数を使用してエラー状態をリセットできます。ErrorBoundary
コンポーネント:FallbackComponent
プロパティにフォールバックUIコンポーネントを指定し、エラーをキャッチしたい子コンポーネント(この場合はMyComponent
)をラップします。onReset
プロパティ: エラーがリセットされたときに実行される関数を指定します。例えば、フォームのリセットや再フェッチなどの処理をここに記述できます。
どんな場合にエラーになるの?
1. レンダリング中のエラー
Reactコンポーネントのrender
メソッドや関数コンポーネントの中でエラーが発生した場合です。例えば、以下のようなケースです:
function ProblematicComponent() {
throw new Error('このコンポーネントはエラーをスローします!');
}
function App() {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<ProblematicComponent />
</ErrorBoundary>
);
}
原因
- 明示的に
throw
でエラーを発生させている。 undefined
やnull
に対して不正な操作を行った。
2. ライフサイクルメソッド内でのエラー
クラスコンポーネントのライフサイクルメソッド内でエラーが発生するケースです。
class ProblematicComponent extends React.Component {
componentDidMount() {
throw new Error('componentDidMount内でエラーが発生しました!');
}
render() {
return <div>正常に動作しています。</div>;
}
}
原因
componentDidMount
やcomponentDidUpdate
で予期しないエラーが発生。- 外部APIからのレスポンスを処理する際のミス(例えば、空のデータに対して操作をしてしまう)。
3. サードパーティライブラリによるエラー
使用しているサードパーティライブラリ内でエラーが発生した場合もキャッチされます。
import ThirdPartyComponent from 'some-library';
function App() {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<ThirdPartyComponent />
</ErrorBoundary>
);
}
原因
- ライブラリのバグ。
- ライブラリの使用方法を間違えた場合。
4. 非同期レンダリング中のエラー
非同期データをレンダリングする際、データが存在しない、または取得に失敗した場合。
function ProblematicComponent({ data }) {
if (!data) {
throw new Error('データが見つかりません!');
}
return <div>{data.name}</div>;
}
function App() {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<ProblematicComponent data={null} />
</ErrorBoundary>
);
}
原因
- 必要なデータが
null
やundefined
である。 - 非同期処理中の状態を考慮せずにレンダリングしている。
5. フォールバックUIのエラー
ErrorBoundary
で指定したフォールバックUI自体がエラーを引き起こす場合。
function ErrorFallback({ error }) {
// errorがない場合を考慮していない
return <div>エラーが発生しました: {error.message}</div>;
}
原因
- フォールバックUI内で
error
やresetErrorBoundary
の扱いを間違えている。 - フォールバックUIが他の依存コンポーネントを使っていて、その中でエラーが発生。
6. 手動でスローしたエラー
アプリケーション内で明示的にthrow
を使ってエラーをスローする場合。
function MyComponent({ condition }) {
if (!condition) {
throw new Error('条件が満たされていません!');
}
return <div>正常に動作しています。</div>;
}
原因
- 条件が満たされない場合に
throw
を使って明示的にエラーを発生させた。 - バリデーションや安全性チェックのためにエラーをスローする。
応用的な使い方
1. 特定のエラータイプに応じた処理
ErrorBoundary
は、発生したエラーの種類に応じて異なるフォールバックUIを表示することができます。
function ErrorFallback({ error, resetErrorBoundary }) {
if (error instanceof SpecificError) {
return (
<div role="alert">
<p>特定のエラーが発生しました:</p>
<pre>{error.message}</pre>
<button onClick={resetErrorBoundary}>再試行</button>
</div>
);
}
return (
<div role="alert">
<p>不明なエラーが発生しました:</p>
<pre>{error.message}</pre>
<button onClick={resetErrorBoundary}>再試行</button>
</div>
);
}
2. ログ機能の追加
エラー発生時にログを記録することで、デバッグやモニタリングが容易になります。
function logErrorToService(error, info) {
// エラー情報を外部サービスに送信する処理をここに記述
}
function App() {
return (
<ErrorBoundary
FallbackComponent={ErrorFallback}
onError={logErrorToService}
>
<MyComponent />
</ErrorBoundary>
);
}
3. 非同期エラーのハンドリング
react-error-boundary
は、非同期処理中に発生したエラーもキャッチできます。
import React, { useEffect } from 'react';
import { useErrorHandler } from 'react-error-boundary';
function MyComponent() {
const handleError = useErrorHandler();
useEffect(() => {
async function fetchData() {
try {
// データ取得処理
} catch (error) {
handleError(error);
}
}
fetchData();
}, [handleError]);
return <div>コンテンツ表示</div>;
}
まとめ
react-error-boundary
のErrorBoundary
コンポーネントを使用することで、Reactアプリケーション内のエラーハンドリングがより簡単かつ強力になります。エラー発生時のユーザー体験を向上させるために、ぜひ活用してみてください。
公式ドキュメントはこちらからご覧いただけます。
関連する記事はこちら↓↓