React Error Boundary って、どんな機能があるのかな?
今回は、React.js コンポーネントのレンダリングやライフサイクル内で発生したエラーをキャッチし、アプリのクラッシュを防ぐための仕組みである Error Boundary について解説します。
React.js の環境構築がまだの場合は、下記より環境構築を行なってください。
Error Boundary とは?
Error Boundary とは、React.js 16 以降で導入された仕組み で、コンポーネントのレンダリングやライフサイクル内で発生したエラーをキャッチ し、アプリ全体のクラッシュを防ぎつつ、代わりにフォールバック UI を表示するための機能 です。
なぜ Error Boundary が必要なの?
React.js 16 以前 では、コンポーネントのレンダリング中にエラーが発生すると、アプリ全体が壊れた状態のまま表示され続けるという問題 がありました。
そこで React.js 16 以降 では Error Boundary が導入され、特定のコンポーネントで発生したエラーをキャッチできる ようになりました。
これにより、UI が真っ白になるのを防ぎ、壊れたコンポーネントだけを安全に置き換えることが可能 になりました。
その結果、アプリ全体のクラッシュを防ぎ、より安全な UI を実現できる ようになりました。
Error Boundary がキャッチできるエラー
Error Boundary は、UI のレンダリングフェーズ(レンダリング・ライフサイクル)で発生したエラーをキャッチする仕組み です。
※ イベントハンドラや非同期処理で発生したエラーは Error Boundary 対象外 となるため、try/catch や Promise.catch などによる 別途エラーハンドリングが必要 になります。
| 種類 | キャッチできる | 具体例 |
|---|---|---|
| レンダリング中のエラー | ✅ | render() 内での undefined 参照など |
| ライフサイクルメソッド内のエラー | ✅ | componentDidMount 内での例外 |
| 子コンポーネントのエラー | ✅ | 配下コンポーネントのレンダーエラー |
| イベントハンドラ内のエラー | ❌ | onClick 内の例外※ try/catch で対応可能 |
| 非同期処理のエラー | ❌ | setTimeout / Promise の例外※ try/catch や Promise.catch で対応可能 |
Error Boundary のインストールと基本的な使い方
それでは、ここから実際に Error Boundary を インストール したり、コンポーネントで利用する 基本的な流れを見ていきましょう。
Error Boundary のインストール
関数コンポーネントでも使用できる react-error-boundary を インストール します
npm install react-error-boundary
Error Boundary の基本的な使い方
コメントアウトのON/OFFで、エラー処理を発生させるコンポーネントを作成
// App.jsx
import { ErrorBoundary } from 'react-error-boundary';
export function MyComponent() {
// コメントアウト外すとエラーが発生する
// throw new Error('エラーを発生させる');
return (
<>
<p>正常に表示</p>
</>
);
}
export default function App() {
return (
<>
<ErrorBoundary fallback={<p>エラーが発生</p>}>
<h2>MyComponent</h2>
<MyComponent />
</ErrorBoundary>
</>
);
}
処理内容
- 「MyComponent 正常に表示」が表示される
- throw new Error のコメントアウトを外し、エラーを発生 させる
- 「エラーが発生」と表示される

ボタンで、エラーをON/リセット(OFF)にするコンポーネントの作成
- resetErrorBoundary: FallbackComponent 内で呼び出すと、Error Boundary の エラー状態をリセットして通常のレンダリングに戻す処理を行う関数
- onReset: Error Boundary の prop として渡し、Error Boundary がリセットされたとき(resetErrorBoundary が呼ばれたとき)に、追加で状態初期化やログ送信などの処理を行うコールバック関数
// App.jsx
import { useState } from "react"; ※追加
import { ErrorBoundary } from "react-error-boundary";
// コンポーネント ※追加
export function MyErrorBoundaryComponent({ throwError }) {
if (throwError) {
throw new Error('エラーが発生!!');
}
return <div>コンポーネントは正常に表示されています。</div>;
}
// フォールバック UI ※追加
function Fallback({ error, resetErrorBoundary }) {
return (
<div>
<p>{error.message}</p>
<button onClick={resetErrorBoundary}>リセット(エラーOFF)</button>
</div>
);
}
export default function App() {
const [throwError, setThrowError] = useState(false);
return (
<>
{/* エラーをオンにするボタン ※エラーがオンの場合、ボタン無効化 */}
<button
onClick={() => setThrowError(true)}
disabled={throwError ? true : false}
>
エラーON
</button>
<ErrorBoundary
FallbackComponent={Fallback}
// エラーのオフ/リセット処理
onReset={() => setThrowError(false)}
>
<h2>MyErrorBoundaryComponent</h2>
<MyErrorBoundaryComponent throwError={throwError} />
</ErrorBoundary>
</>
);
}
処理内容
- 「MyErrorBoundaryComponent」と「コンポーネントは正常に表示されています」と「エラーON」のボタンが表示される
- 「エラーON」ボタンを押すと、「エラーが発生!!」と「リセット(エラーOFF)」 ボタンが表示され、「エラーON」ボタンが無効化される
- 「リセット(エラーOFF)」ボタンを押すと、再び「MyErrorBoundaryComponent」と「コンポーネントは正常に表示されています」と「エラーON」のボタンが表示される
- 再度「エラーON」ボタンを押すと、再び「エラーが発生!!」と「リセット(エラーOFF)」 ボタンが表示され、「エラーON」ボタンが無効化される
- 再度「リセット(エラーOFF)」ボタンを押すと、また「MyErrorBoundaryComponent」と「コンポーネントは正常に表示されています」と「エラーON」のボタンが表示される

イベントハンドラのエラーと非同期処理のエラーの場合のコンポーネントの作成
イベントハンドラのエラー と 非同期処理のエラー の場合、Error Boundary でキャッチすることはできないが、try/catch と useErrorBoundary を用いてエラーをキャッチする
イベントハンドラ内や非同期処理(Promise / setTimeout)で発生したエラー は、通常の Error Boundary では 自動的にキャッチされない ため、try/catch や Promise.catch でエラーをキャッチ し、useErrorBoundary を使って Error Boundary にエラーを渡す必要があります。
// App.jsx
import { useState } from "react";
import { ErrorBoundary, useErrorBoundary } from "react-error-boundary"; ※追加
// フォールバック UI ※追加
function ErrorBoundaryFallback({ error, resetErrorBoundary }) {
return (
<div>
<p>エラー: {error.message}</p>
<button onClick={resetErrorBoundary}>リセット</button>
</div>
);
}
function MyUseErrorBoundaryComponent() {
const { showBoundary } = useErrorBoundary();
const [count, setCount] = useState(0);
// イベントハンドラのエラー例
const clickEventHandle = () => {
try {
throw new Error('クリックイベントで発生したエラー!');
} catch (err) {
showBoundary(err);
}
};
// 非同期処理のエラー例
const asyncHandle = () => {
const timer = setTimeout(() => {
try {
throw new Error('setTimeout で発生した非同期エラー!');
} catch (err) {
showBoundary(err);
}
}, 2000);
return () => clearTimeout(timer);
};
// Promise のエラー例
const promiseHandle = () => {
Promise.reject(new Error('Promise で発生した非同期エラー!')).catch(
showBoundary,
);
};
return (
<div>
<p>クリックカウント: {count}</p>
<button onClick={() => setCount((cnt) => cnt + 1)}>カウント増加</button>
<button onClick={clickEventHandle}>
クリックイベントハンドラ でエラー発生
</button>
<button onClick={asyncHandle}>setTimeout でエラー発生</button>
<button onClick={promiseHandle}>Promise でエラー発生</button>
</div>
);
}
export default function App() {
return (
<>
<ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
<h2>MyUseErrorBoundaryComponent</h2>
<MyUseErrorBoundaryComponent />
</ErrorBoundary>
</>
);
}
処理内容
- 「MyUseErrorBoundaryComponent」と「クリックカウント: 0」、「カウント増加」ボタン、「クリックイベントハンドラ でエラー発生」ボタン、「setTimeout でエラー発生」ボタン、「Promise でエラー発生」のボタンが表示される
- 「カウント増加」ボタンを5回押しても、エラーは発生せず、「クリックカウント: 5」になる
- 「クリックイベントハンドラ でエラー発生」ボタンを押すと、「クリックイベントで発生したエラー!」と「リセット」ボタンが表示され、「リセット」ボタンで エラー前の画面に戻る
- 「setTimeout でエラー発生」ボタンを押すと、2秒後 に「setTimeout で発生した非同期エラー!」と「リセット」ボタンが表示され、「リセット」ボタンで エラー前の画面に戻る
- 「Promiseでエラー発生」ボタンを押すと、「Promise で発生した非同期エラー!」と「リセット」ボタンが表示され、「リセット」ボタンで エラー前の画面に戻る

まとめ
Error Boundary について解説してきましたが、いかがでしたでしょうか?
Error Boundary は、コンポーネントのレンダリングやライフサイクル内で発生したエラーをキャッチ し、UI が真っ白になるのを防ぎ、通常の画面の代わりにエラー用の画面へ切り替える ための仕組み です。
まずは Error Boundary の基本的な使い方をしっかり押さえ、小さな コンポーネント で試しながら、より安定した品質の高いコード で開発できるようになっていきましょう。



コメント