Reactエラー境界コンポーネント処理

Reactエラー境界コンポーネント処理

React 16の内容です。最新技術ではありませんが、ドキュメントで調べるまであまり話題に上がらなかった部分です。実はとても便利な部分です。まとめてみましょう〜

React でキャッチされない JS エラーが発生すると、アプリケーション全体がクラッシュし、コンポーネント ツリー全体がアンマウントされる可能性があります。これは React 16 以降に当てはまります。しかし同時に、React はエラー境界という新しい概念も導入しました。

定義、それは

エラー境界は、子コンポーネント ツリー内の任意の場所で JavaScript エラーをキャッチ (印刷など) して処理し、必要に応じて代替 UI をレンダリングできるコンポーネントです。

try-catch と同様に動作しますが、エラー境界は React コンポーネントにのみ使用されます。

クラス コンポーネントのみがエラー境界コンポーネントになることができます。エラー境界は、サブコンポーネント内のエラーのみをキャプチャでき、それ自体のエラーはキャプチャできません。

エラー境界は、レンダリング中、ライフサイクル中、およびコンポーネント ツリー全体のコンストラクター内でエラーをキャッチします。エラー境界処理がなければ、レンダリングされた子コンポーネント ツリーは依然として折りたたまれますが、これは明らかに望ましいことではありません。

エラー境界を段階的に使用する方法を示す例を見てみましょう。

デフォルトクラス ErrorTest をエクスポートし、Component を拡張します {
  コンストラクタ(props) {
    スーパー(小道具);
  }
  与える() {
    戻る (
      <div>
        <バグカウンタ></バグカウンタ>
        <span>私の名前はダンです</span>
      </div>
    );
  }
}

// バグエラーコンポーネントクラス BugCounter は Component を拡張します {
  コンストラクタ(props) {
    スーパー(小道具);
    この状態 = {
      カウンター: 0,
    };
  }
  クリック = () => {
    this.setState(({ counter }) => ({ counter: counter + 1 }));
  };
  与える() {
    if (this.state.counter === 5) {
      新しいエラーをスローします("クラッシュしました!");
    }
    戻る (
      <div>
        <h3 onClick={this.click}>{this.state.counter}</h3>
      </div>
    );
  }
}

上記コードのレンダリング結果(スタイルは無視):

数字の0をクリックすると徐々に増加します。しかし、数値が5に等しい場合、コンポーネントはErrorをスローします。

このErrorによりDemo全体がクラッシュし、外部の<span>my name is dan</span>も表示されなくなります。現時点では、エラー境界は追加されていません。

本番モードでは、白い画面が表示され、コンソールにエラーが報告されます。

getDerivedStateFromError と componentDidCatch

この種のクラッシュを処理するにはエラー境界が必要です。エラー境界を定義するにはどうすればよいでしょうか?

コンポーネントを定義し、 static getDerivedStateFromError()またはcomponentDidCatch()ライフサイクル メソッドを実装します (両方を実装することも、いずれかを選択することもできます)。このコンポーネントはエラー境界になります。

これら 2 つのライフサイクル機能については、次のように要約されているリンクから確認できます。

コンポーネントDidCatch(エラー、情報)

errorはスローされたエラー オブジェクトであり、 infoにはエラーの原因となったコンポーネントのスタック トレースが含まれます。関数はコミットフェーズ中に呼び出されます。副作用を起こす可能性があります。

静的 getDerivedStateFromError(エラー)

子コンポーネントがエラーをスローした後に、スローされたエラーを引数として呼び出されます。状態を更新するには値を返す必要があります。この関数はレンダリング フェーズ中に呼び出され、副作用は許可されません。エラーをキャッチした後に副作用を実行する必要がある場合は、 componentDidCatchで実行する必要があります。

エラー境界コンポーネントの作成

組み合わせメソッドを使用して、エラー境界コンポーネントを追加し、使用するコンポーネントをラップすることができます。このコンポーネントには次の効果が必要です:

  • サブコンポーネントのエラーをキャプチャし、コンポーネント内のエラーステータスを記録する
  • エラー状態では代替UIを表示し、通常状態ではサブコンポーネントを表示します。

すると次のようになります:

ErrorBoundaryクラスはReact.Componentを拡張します。
  コンストラクタ(props) {
    スーパー(小道具);
    this.state = {hasError: false };
  }

  静的 getDerivedStateFromError(エラー) {
    // 次のレンダリングで劣化した UI を表示できるように状態を更新します
    {hasError: true } を返します。
  }

  コンポーネントDidCatch(エラー、エラー情報) {
    // エラー ログをサーバーに報告することもできます logErrorToMyService(error, errorInfo);
  }

  与える() {
    if (this.state.hasError) {
      // ダウングレードされた UI をカスタマイズしてレンダリングできます。 return <h1>Something went wrong.</h1>;
    }

    this.props.children を返します。 
  }
}

エラーをキャッチした後の副作用は、カスタマイズされ、サーバーにアップロードされるか、 stateレコードを使用してページに表示されます。

コンポーネントDidCatch(エラー、エラー情報) {
  // 以下のコンポーネントでエラーをキャッチし、エラーメッセージとともに再レンダリングします
  this.setState({
    エラー: エラー、
    エラー情報: エラー情報
  })
}

キャプチャ処理

すべてのコードを追加し、問題のあるコンポーネントをエラー境界コンポーネントでラップして、結果を確認します。

「react」からコンポーネントをインポートします。

デフォルトクラス ErrorTest をエクスポートし、Component を拡張します {
  与える() {
    戻る (
      <div>
        <エラー境界>
          <バグカウンタ></バグカウンタ>
        </エラー境界>
        <span>私の名前はダンです</span>
      </div>
    );
  }
}

// バグエラーコンポーネントクラス BugCounter は Component を拡張します {
  コンストラクタ(props) {
    スーパー(小道具);
    この状態 = {
      カウンター: 0,
    };
  }
  クリック = () => {
    this.setState(({ counter }) => ({ counter: counter + 1 }));
  };
  与える() {
    if (this.state.counter === 5) {
      新しいエラーをスローします("クラッシュしました!");
    }
    戻る (
      <div>
        <h3 onClick={this.click}>{this.state.counter}</h3>
      </div>
    );
  }
}

// エラー境界処理コンポーネントクラス ErrorBoundary は Component を拡張します {
  コンストラクタ(props) {
    スーパー(小道具);
    this.state = {hasError: false };
  }

  静的 getDerivedStateFromError(エラー) {
    // 次のレンダリングで劣化した UI を表示できるように状態を更新します
    {hasError: true } を返します。
  }

  与える() {
    if (this.state.hasError) {
      // ダウングレードされた UI をカスタマイズしてレンダリングできます。 return <h1>Something went wrong.</h1>;
    }

    this.props.children を返します。
  }
}

例外をスローすると開発モードではまだエラーが報告されますが、 yarn buildを使用してからhttp-server経由でハングアップし、本番ページにアクセスします。

throw errorによりコンソール エラーが発生しているにもかかわらず、 my name is danの表示は影響を受けていないことがわかります。つまり、エラー境界内のサブコンポーネント エラーは、他の外部コンポーネントや要素に影響を与えません。

範囲

エラー境界は、サブコンポーネントのライフ サイクルとレンダリング関数のエラーを処理するために使用されます。イベント ハンドラーの場合、レンダリング中にはトリガーされません。イベント ハンドラーによってスローされる例外には、 try catch使用する必要があります。

エラー境界では、次のシナリオではエラーをキャッチできません。

  • イベント処理
  • 非同期コード
  • サーバーサイドレンダリング
  • エラー境界自体によってスローされたエラー(子コンポーネントではない)

エラー境界に関しては、 Reactの公式demoを試してみる価値があります。

https://codepen.io/gaearon/pen/wqvxGa?editors=0010

参照:

https://zh-hans.reactjs.org/docs/error-boundaries.html

https://zh-hans.reactjs.org/docs/react-component.html

https://codepen.io/gaearon/pen/wqvxGa?editors=0010

React error boundary コンポーネントの取り扱いに関する記事はこれで終了です。React error boundary に関するより詳しい内容については、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • 最も単純な ErrorBoundary コンポーネントをカプセル化して、React 例外を処理する
  • React でのポータルとエラー境界処理の実装
  • React 16における例外処理の詳細な説明
  • Reactワークフローとエラー境界の実装プロセスの説明

<<:  Linux シェル環境での Zabbix API の使用

>>:  MySQLクエリの文字セットの不一致の問題を解決する方法

推薦する

ウェブデザイナーのための超便利なツール 50 選

ウェブデザイナーになるのは簡単ではありません。デザインやアーキテクチャを考慮するだけでなく、さまざま...

MySQL 5.7 スレーブノードからマルチスレッド マスター スレーブ レプリケーションを構成する方法の詳細な説明

序文MySQL は MySQL 5.6 からマルチスレッド レプリケーションをサポートしていますが、...

ファイルをアップロードするときに enctype フィールドを使用する理由は何ですか?

FORM 要素の enctype 属性は、フォーム データがサーバーに送信されるときに使用されるエン...

Zabbix 5.0 ディスク自動検出と読み取り/書き込み監視の問題を分析する

ディスクを自動的に検出する構成キーの値注: このキー値は Linux プラットフォームでのみサポート...

Linux での MySQL のインストールに関する詳細なチュートリアル

1. MySQLサービスをシャットダウンする# service mysqld stop 2. rpm...

WeChatアプレットのスクロールビューが左右の連動を実現

この記事では、WeChatアプレットのスクロールビューの左右連動を実現するための具体的なコードを参考...

CSS 完全な視差スクロール効果

1. 何ですか視差スクロールとは、複数の背景レイヤーを異なる速度で動かすことで、3次元のモーション...

Windows Server 2016 に Docker をインストールする方法

最近、Microsoft は Docker をネイティブにサポートする Windows Server...

Vue3とTypeScriptを組み合わせたプロジェクト開発の実践記録

目次概要1. コンポジションAPI 1. ref と reactive の違いは何ですか? 2. 周...

HTML スクロールバーのテキストエリア属性の設定

1.オーバーフローコンテンツのオーバーフロー設定(設定されたオブジェクトにスクロールバーを表示するか...

HTML入門チュートリアル HTMLタグ記号をすぐにマスター

補足<br />HTML について何も知らず、HTML の始め方がまだわからない場合は、...

パゴダパネルとドッカーを使用して Gogs をインストールするプロセス全体

目次1 Baota Software StoreにDockerをインストールする2 ゴグスイメージを...

無効にしてHTMLフォーム入力を送信した後にフォーム値が取得されない問題を解決する方法

フォーム入力ボックスの入力をdisable属性に設定して送信すると、入力ボックスの値を取得できなくな...

Docker に Zookeeper を素早くインストールする方法の詳細なチュートリアル

Docker で Zookeeper を素早くインストール会社を変わってから長らくZookeeper...

素晴らしいCSS属性MASKの詳しい説明

この記事では、CSS の非常に興味深い属性マスクを紹介します。名前が示すように、マスクはマスクと翻訳...