日本語

React SuspenseとErrorBoundaryをマスターして、堅牢なローディング状態管理と優雅なエラー処理を実現しましょう。耐障害性が高く、使いやすいアプリケーションを構築する方法を学びます。

React SuspenseとErrorBoundary:高度なローディングとエラー処理

React SuspenseとErrorBoundaryは、開発者がより耐障害性が高く、使いやすいアプリケーションを構築できるようにする強力な機能です。これらは、ローディング状態と予期しないエラーを宣言的に処理する方法を提供し、全体的なユーザーエクスペリエンスを向上させ、開発プロセスを簡素化します。この記事では、React SuspenseとErrorBoundaryを効果的に使用するための包括的なガイドを提供し、基本的な概念から高度なテクニックまでを網羅します。

Understanding React Suspense

React Suspenseは、特定の条件が満たされるまで、通常は非同期操作からのデータの可用性まで、コンポーネントのレンダリングを「中断」するメカニズムです。これにより、データのロードを待機している間、ローディングインジケーターなどのフォールバックUIを表示できます。Suspenseは、ローディング状態の管理を簡素化し、手動による条件付きレンダリングの必要性を排除し、コードの可読性を向上させます。

Key Concepts of Suspense

Basic Implementation of Suspense

Suspenseを使用してデータのフェッチ中にローディングインジケーターを表示する方法の簡単な例を次に示します。


import React, { Suspense } from 'react';

// Simulate fetching data (e.g., from an API)
const fetchData = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ name: 'John Doe', age: 30 });
    }, 2000);
  });
};

// Create a resource that Suspense can use
const createResource = (promise) => {
  let status = 'pending';
  let result;
  let suspender = promise().then(
    (r) => {
      status = 'success';
      result = r;
    },
    (e) => {
      status = 'error';
      result = e;
    }
  );

  return {
    read() {
      if (status === 'pending') {
        throw suspender;
      } else if (status === 'error') {
        throw result;
      }

      return result;
    },
  };
};

const userData = createResource(fetchData);

// Component that reads from the resource
const UserProfile = () => {
  const data = userData.read();
  return (
    

Name: {data.name}

Age: {data.age}

); }; const App = () => { return ( Loading user data...
}> ); }; export default App;

In this example:

Suspense with Code Splitting

Suspenseは、React.lazyとともに使用して、コード分割を実装することもできます。これにより、必要な場合にのみコンポーネントをロードできるため、初期ページロードパフォーマンスが向上します。


import React, { Suspense, lazy } from 'react';

// Lazy load the MyComponent component
const MyComponent = lazy(() => import('./MyComponent'));

const App = () => {
  return (
    Loading component...}>
      
    
  );
};

export default App;

In this example:

Understanding Error Boundaries

ErrorBoundaryは、子コンポーネントツリー内のJavaScriptエラーをキャッチし、それらのエラーをログに記録し、アプリケーション全体をクラッシュさせる代わりにフォールバックUIを表示するReactコンポーネントです。これらは、予期しないエラーを適切に処理し、ユーザーエクスペリエンスを向上させ、アプリケーションをより堅牢にする方法を提供します。

Key Concepts of Error Boundaries

Basic Implementation of Error Boundaries

ErrorBoundaryを作成する方法の簡単な例を次に示します。


import React, { Component } from 'react';

class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    console.error(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return 

Something went wrong.

; } return this.props.children; } } export default ErrorBoundary;

In this example:

Using Error Boundaries

`ErrorBoundary` コンポーネントを使用するには、保護するコンポーネントをラップするだけです。


import React from 'react';
import ErrorBoundary from './ErrorBoundary';

const MyComponent = () => {
  // Simulate an error
  throw new Error('An error occurred!');
};

const App = () => {
  return (
    
      
    
  );
};

export default App;

この例では、`MyComponent` でエラーが発生した場合、`ErrorBoundary` コンポーネントがエラーをキャッチし、フォールバックUIを表示します。

Combining Suspense and Error Boundaries

SuspenseとErrorBoundaryを組み合わせることで、非同期操作のための堅牢で包括的なエラー処理戦略を提供できます。中断する可能性のあるコンポーネントをSuspenseとErrorBoundaryの両方でラップすることにより、ローディング状態と予期しないエラーの両方を適切に処理できます。

Example of Combining Suspense and Error Boundaries


import React, { Suspense } from 'react';
import ErrorBoundary from './ErrorBoundary';

// Simulate fetching data (e.g., from an API)
const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // Simulate a successful data fetch
      // resolve({ name: 'John Doe', age: 30 });

      // Simulate an error during data fetching
      reject(new Error('Failed to fetch user data'));

    }, 2000);
  });
};

// Create a resource that Suspense can use
const createResource = (promise) => {
  let status = 'pending';
  let result;
  let suspender = promise().then(
    (r) => {
      status = 'success';
      result = r;
    },
    (e) => {
      status = 'error';
      result = e;
    }
  );

  return {
    read() {
      if (status === 'pending') {
        throw suspender;
      } else if (status === 'error') {
        throw result;
      }

      return result;
    },
  };
};

const userData = createResource(fetchData);

// Component that reads from the resource
const UserProfile = () => {
  const data = userData.read();
  return (
    

Name: {data.name}

Age: {data.age}

); }; const App = () => { return ( Loading user data...}> ); };

In this example:

Advanced Techniques and Best Practices

Optimizing Suspense Performance

Custom Error Boundaries

カスタムErrorBoundaryを作成して、特定の種類のエラーを処理したり、より有益なエラーメッセージを提供したりできます。たとえば、発生したエラーの種類に基づいて異なるフォールバックUIを表示するErrorBoundaryを作成できます。

Server-Side Rendering (SSR) with Suspense

Suspenseは、サーバーサイドレンダリング(SSR)で使用して、初期ページロードパフォーマンスを向上させることができます。SSRを使用する場合、アプリケーションの初期状態をサーバーで事前にレンダリングし、残りのコンテンツをクライアントにストリーミングできます。Suspenseを使用すると、SSR中の非同期データフェッチを処理し、データがストリーミングされている間にローディングインジケーターを表示できます。

Handling Different Error Scenarios

Consider these different error scenarios and how to handle them:

Global Error Handling

ErrorBoundaryによってキャッチされないエラーをキャッチするために、グローバルエラー処理メカニズムを実装します。これは、グローバルエラーハンドラーを使用するか、アプリケーション全体をErrorBoundaryでラップすることで実行できます。

Real-World Examples and Use Cases

E-commerce Application

eコマースアプリケーションでは、Suspenseを使用して製品データのフェッチ中にローディングインジケーターを表示し、ErrorBoundaryを使用してチェックアウトプロセス中に発生するエラーを処理できます。たとえば、日本のユーザーが米国にあるオンラインストアを閲覧していると想像してください。製品の画像と説明のロードに時間がかかる場合があります。Suspenseは、このデータが世界のほぼ半分を回る可能性のあるサーバーからフェッチされている間、単純なローディングアニメーションを表示できます。一時的なネットワークの問題(世界中のさまざまなインターネットインフラストラクチャで一般的)が原因で決済ゲートウェイが失敗した場合、ErrorBoundaryは、後でもう一度試すように促すユーザーフレンドリーなメッセージを表示できます。

Social Media Platform

ソーシャルメディアプラットフォームでは、Suspenseを使用してユーザープロファイルと投稿のフェッチ中にローディングインジケーターを表示し、ErrorBoundaryを使用して画像またはビデオのロード時に発生するエラーを処理できます。インドから閲覧しているユーザーは、ヨーロッパのサーバーでホストされているメディアのロード時間が遅くなる可能性があります。Suspenseは、コンテンツが完全にロードされるまでプレースホルダーを表示できます。特定のユーザーのプロファイルデータが破損している場合(まれですが可能)、ErrorBoundaryはソーシャルメディアフィード全体のクラッシュを防ぎ、「ユーザープロファイルをロードできません」のような単純なエラーメッセージを表示できます。

Dashboard Application

ダッシュボードアプリケーションでは、Suspenseを使用して複数のソースからデータをフェッチしている間にローディングインジケーターを表示し、ErrorBoundaryを使用してチャートまたはグラフのロード時に発生するエラーを処理できます。ロンドンにいる金融アナリストがグローバル投資ダッシュボードにアクセスする場合、世界中の複数の取引所からデータをロードしている可能性があります。Suspenseは、各データソースのローディングインジケーターを提供できます。1つの取引所のAPIがダウンしている場合、ErrorBoundaryはその取引所のデータに固有のエラーメッセージを表示し、ダッシュボード全体が使用できなくなるのを防ぎます。

Conclusion

React SuspenseとErrorBoundaryは、耐障害性が高く、使いやすいReactアプリケーションを構築するための不可欠なツールです。Suspenseを使用してローディング状態を管理し、ErrorBoundaryを使用して予期しないエラーを処理することで、全体的なユーザーエクスペリエンスを向上させ、開発プロセスを簡素化できます。このガイドでは、基本的な概念から高度なテクニックまで、SuspenseとErrorBoundaryの包括的な概要を提供しました。この記事で概説されているベストプラクティスに従うことで、最も困難なシナリオでも処理できる、堅牢で信頼性の高いReactアプリケーションを構築できます。

Reactが進化し続けるにつれて、SuspenseとErrorBoundaryは、最新のWebアプリケーションの構築においてますます重要な役割を果たす可能性があります。これらの機能を習得することで、時代の先を行き、優れたユーザーエクスペリエンスを提供できます。