Join the discussion
Comments
Loading comments...
Cookie preferences
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Join the discussion
Loading comments...
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
ReactがコンポーネントツリーのエラーをキャッチしてフォールバックUIを表示する方法。
エラーバウンダリは、子コンポーネントツリー内のどこでもJavaScriptエラーをキャッチし、それらのエラーをログに記録し、アプリケーション全体をクラッシュさせる代わりにフォールバックUIを表示するReactクラスコンポーネントです。JavaScriptのcatch{'}ブロックのように機能しますが、コンポーネントツリー向けです。エラーバウンダリはレンダリング中、ライフサイクルメソッド内、およびその下のツリー全体のコンストラクタ内のエラーをキャッチします。
サブツリー内のいずれかのコンポーネントがレンダリング中(またはライフサイクルメソッド内で)エラーをスローすると、ReactはFiberツリーを通じて上方向にエラーを伝播させ始め、最も近いエラーバウンダリを探します。
Reactは親Fiberを上方向に走査します。getDerivedStateFromErrorまたはcomponentDidCatchを実装したクラスコンポーネントを見つけると、そこで停止します。一つも見つからずにルートに到達すると、アプリ全体がアンマウントされます。
Reactはバウンダリクラス上でgetDerivedStateFromError(error)を呼び出します。この静的メソッドは新しいstate(例:'{' hasError: true '}')を返し、バウンダリがフォールバックUIで再レンダリングされます。
フォールバックUIが表示された後、ReactはcomponentDidCatch(error, errorInfo)を呼び出します — Sentryのようなロギングサービスにエラーを送信するのに適した場所です。
バウンダリコンポーネントはstateを確認し(hasError)、子(通常)またはフォールバックJSXエレメントのどちらかをレンダリングします。バウンダリの外側のアプリの残りの部分は通常通り動作し続けます。
静的クラスメソッド。子がスローしたときのレンダーフェーズ中に呼び出されます。フォールバックレンダリングをトリガーするための新しいstateを返します。
インスタンスメソッド。フォールバックがレンダリングされた後のコミットフェーズ中に呼び出されます。エラーロギングに使用します。エラー + コンポーネントスタックを受け取ります。
エラーは例外がコールスタックを上方向にバブリングするのと同様に、Fiberツリーを通じて最も近いバウンダリまでバブリングします。
バウンダリのkey propを変更することでリセットできます。これによりReactはサブツリー全体をアンマウントして新しい状態で再マウントします。
1class ErrorBoundary extends React.Component {2 state = { hasError: false, error: null };34 static getDerivedStateFromError(error) {5 // Called during render — must be pure, no side effects6 return { hasError: true, error };7 }89 componentDidCatch(error, info) {10 // Called after commit — safe for side effects like logging11 logErrorToSentry(error, info.componentStack);12 }1314 render() {15 if (this.state.hasError) {16 return <FallbackUI error={this.state.error} />;17 }18 return this.props.children;19 }20}2122// Usage:23<ErrorBoundary>24 <MyComponent /> {/* If this throws, ErrorBoundary catches it */}25</ErrorBoundary>
エラーバウンダリなしでは、単一の未処理レンダーエラーがReactアプリ全体をクラッシュさせ、空白の画面を表示します。エラーバウンダリにより、失敗をUIの分離されたセクションに隔離できます — アプリの残りの部分は動作し続けます。これは、すべてのエッジケースを予測できない本番アプリにとって非常に重要です。
Your e-commerce app crashes in production when a product with malformed data renders. The entire page goes white and users see nothing — you lose the sale and have no visibility into what happened.
Without error boundaries, a single component throwing an error unmounts the ENTIRE React tree. The user sees a blank page. No error tracking fires because the crash happened during rendering, not in a try/catch block.
Wrap critical sections in error boundaries with strategic granularity: one around the product card, one around the cart, one around the whole page. Use componentDidCatch to send the error + componentStack to Sentry. Show a helpful fallback UI ('Something went wrong, refresh to try again') instead of a blank page.
Takeaway: Error boundaries are your PRODUCTION safety net. Place them at route level (catch everything), feature level (isolate failures), and widget level (for third-party components you don't control). Always log to an error tracking service in componentDidCatch.
You embed a third-party analytics chart widget in your dashboard. After a library update, the widget occasionally throws during rendering due to unexpected data formats.
The chart crash cascades — it's nested inside your dashboard layout, so the error propagates up and takes down the entire dashboard, including the navigation, sidebar, and all other widgets.
Wrap ONLY the third-party widget in its own error boundary. The fallback shows a placeholder ('Chart unavailable — refresh to retry'). The rest of the dashboard remains fully functional. Users can still use all other features while you investigate the chart issue.
Takeaway: Error boundaries give you component-level fault isolation, similar to microservice circuit breakers. Treat each third-party or unstable component as an isolated fault domain.