序文完璧な人間はいないのですから、コードには常にエラーが存在します。エラーはひどいものではありません。重要なのは、エラーにどう対処するかです。
エラー境界EerrorBoundary はバージョン 16 で登場しました。誰かが私にバージョン 15 はどうなのかと尋ねました。私はそれを聞きたくありませんでした。とにかく私はバージョン 16 を使っていますし、もちろん 15 には ErrorBoundary の公式サイトには詳しい紹介がありますが、これは重要ではありません。重要なのは、どのような例外をキャプチャできるかです。
コンストラクタ(props) { スーパー(小道具); this.state = {hasError: false }; } コンポーネントDidCatch(エラー、情報) { // フォールバックUIを表示する this.setState({hasError: true }); // エラーをエラー報告サービスに記録することもできます logErrorToMyService(エラー、情報); } 与える() { if (this.state.hasError) { // カスタムフォールバックUIをレンダリングできます <h1>問題が発生しました。</h1> を返します。 } this.props.children を返します。 } } <エラー境界> <マイウィジェット /> </エラー境界> オープンソースの世界は素晴らしいです。偉大な作者がすでに react-error-boundary のような優れたライブラリをカプセル化しています。 'react-error-boundary' から {ErrorBoundary} をインポートします。 関数 ErrorFallback({error, resetErrorBoundary}) { 戻る ( <div ロール="アラート"> <p>問題が発生しました:</p> <pre>{エラーメッセージ}</pre> <button onClick={resetErrorBoundary}>もう一度お試しください</button> </div> ) } 定数ui = ( <エラー境界 フォールバックコンポーネント = {ErrorFallback} onReset={() => { // エラーが再発しないようにアプリの状態をリセットします }} > <エラーが発生する可能性のあるコンポーネント /> </エラー境界> ) 残念ながら、エラー境界では次のエラーは検出されません。
原文は公式ウェブサイトintroducing-error-boundariesでご覧いただけます。 この記事の目的は、イベント ハンドラーのエラーをキャプチャすることです。 しかし、イベント ハンドラーがこんなにたくさんあるなんて、いったいいくつ書かなければならないのでしょうか? 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 ハンドルクリック() { 試す { // 何かを投げる可能性がある } キャッチ(エラー){ this.setState({エラー}); } } エラー境界を超えてまず、例外をキャプチャできる手段と範囲を示す表を見てみましょう。
トライ/キャッチ同期例外と async/await 例外の両方をキャッチできます。 window.onerror、エラーイベントwindow.addEventListener('error', this.onError, true); window.onerror = this.onError window.addEventListener('error') は、window.onerror よりも多くのリソースをキャプチャし、例外を記録できます。 未処理の拒否最後のパラメータが true であることに注意してください。 window.removeEventListener('unhandledrejection', this.onReject, true) キャッチされていない Promise 例外をキャッチします。 XMLHttpRequestとフェッチXMLHttpRequest は扱いやすく、独自の onerror イベントを備えています。 ErrorBoundary.prototype.componentDidMount = 関数 () { // イベントキャッチ window.addEventListener('error', this.catchError, true); // 非同期コード window.addEventListener('unhandledrejection', this.catchRejectEvent, true); }; 使用: 'react-error-catch' から ErrorCatch をインポートします。 定数App = () => { 戻る ( <エラーキャッチ アプリ="react-catch" ユーザー="cxyuns" 遅延={5000} 最大={1} フィルター={[]} onCatch={(エラー) => { console.log('エラーが報告されました'); // 例外情報をバックエンドに報告し、動的にタグを作成します。new Image().src = `http://localhost:3000/log/report?info=${JSON.stringify(errors)}` }} > <メイン /> </ErrorCatch>) } エクスポートデフォルト 拍手、拍手。 イベントハンドラでの例外キャッチ例私のアイデアは非常にシンプルで、デコレータを使用して元のメソッドを書き換えます。 @methodCatch({ message: "注文の作成に失敗しました", toast: true, report:true, log:true }) 非同期createOrder() { 定数データ = {...}; const res = createOrder() を待機します。 (!res || res.errCode !== 0)の場合{ Toast.error("注文の作成に失敗しました"); を返します。 } ....... 例外を引き起こす可能性のあるその他のコード... Toast.success("注文が正常に作成されました"); } 次の 4 つのパラメータに注意してください。
おそらく、これは確実かつ不合理なニュースだと言うでしょう。他に何かニュースがあったらどうしますか? @methodCatch({ message: "注文の作成に失敗しました", toast: true, report:true, log:true }) 非同期createOrder() { 定数データ = {...}; const res = createOrder() を待機します。 (!res || res.errCode !== 0)の場合{ Toast.error("注文の作成に失敗しました"); を返します。 } ....... 例外を引き起こす可能性のあるその他のコード... throw new CatchError("注文の作成に失敗しました。管理者に連絡してください", { トースト:本当、 報告: 本当、 ログ: 偽 }) Toast.success("注文が正常に作成されました"); } はい、その通りです。カスタム CatchError をスローすることで、デフォルトのオプションをオーバーライドできます。 タイプ定義エクスポートインターフェースCatchOptions { レポート?: ブール値; メッセージ?: 文字列; ログ?: ブール値; トースト?: ブール値; } // const.ts に記述する方が合理的です export const DEFAULT_ERROR_CATCH_OPTIONS: CatchOptions = { 報告: 本当、 メッセージ:「不明な例外」、 ログ: 真、 トースト: 偽 } カスタム CatchError"@typess/errorCatch" から CatchOptions、DEFAULT_ERROR_CATCH_OPTIONS をインポートします。 エクスポートクラスCatchErrorはErrorを拡張します{ パブリック __type__ = "__CATCH_ERROR__"; /** * キャッチされたエラー * @param message メッセージ * @options その他のパラメータ */ コンストラクター(メッセージ: 文字列、パブリックオプション: CatchOptions = DEFAULT_ERROR_CATCH_OPTIONS) { super(メッセージ); } } デコレーター"@components/Toast" から Toast をインポートします。 "@typess/errorCatch" から CatchOptions、DEFAULT_ERROR_CATCH_OPTIONS をインポートします。 "@util/error/CatchError" から CatchError をインポートします。 const W_TYPES = ["文字列", "オブジェクト"]; エクスポート関数 methodCatch(options: string | CatchOptions = DEFAULT_ERROR_CATCH_OPTIONS) { const type = typeof オプション; opt : CatchOptions; を設定します。 if (options == null || !W_TYPES.includes(type)) { // null または文字列またはオブジェクトではない opt = DEFAULT_ERROR_CATCH_OPTIONS; } else if (typeof options === "string") { // 文字列 opt = { ...DEFAULT_ERROR_CATCH_OPTIONS、 メッセージ: オプション || DEFAULT_ERROR_CATCH_OPTIONS.message、 } } else { // 有効なオブジェクト opt = { ...DEFAULT_ERROR_CATCH_OPTIONS, ...options } } 戻り関数 (_target: any、_name: string、記述子: PropertyDescriptor): any { const oldFn = 記述子.値; Object.defineProperty(記述子、"値"、{ 得る() { 非同期関数プロキシ(...引数: any[]) { 試す { const res = await oldFn.apply(this, args); res を返します。 } キャッチ (エラー) { // if (err instanceof CatchError) { if(err.__type__ == "__CATCH_ERROR__"){ err = err を CatchError として返します。 const mOpt = { ...opt, ...(err.options || {}) }; (mOpt.log)の場合{ console.error("asyncMethodCatch:", mOpt.message || err.message , err); } if (mOpt.report) { // やるべきこと:: } if (mOpt.toast) { Toast.error(mOpt.message); } } それ以外 { 定数メッセージ = err.message || opt.message; console.error("asyncMethodCatch:", メッセージ, エラー); if (opt.toast) { Toast.error(メッセージ); } } } } プロキシ_bound = true; プロキシを返します。 } }) 記述子を返します。 } } 総括するデコレータを使用して、エラーをキャプチャする元のメソッドを書き換えます。エラー クラスをカスタマイズしてスローし、デフォルトのオプションをオーバーライドします。柔軟性が向上しました。 @methodCatch({ message: "注文の作成に失敗しました", toast: true, report:true, log:true }) 非同期createOrder() { 定数データ = {...}; const res = createOrder() を待機します。 (!res || res.errCode !== 0)の場合{ Toast.error("注文の作成に失敗しました"); を返します。 } Toast.success("注文が正常に作成されました"); ....... 例外を引き起こす可能性のあるその他のコード... throw new CatchError("注文の作成に失敗しました。管理者に連絡してください", { トースト:本当、 報告: 本当、 ログ: 偽 }) } 次のステップ次のステップは何でしょうか? 一歩ずつ進んでいきましょう。 結果の拡大 フォロー クラスAAA{ フォロー メソッド = () => { } } 抽象的、抽象的、抽象的 さようなら。 最後にエラー境界 React で例外をエレガントに捕捉する方法についての記事はこれで終わりです。React で例外を捕捉する方法についての詳細は、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: MySQLデータベース移行により、大量のデータを迅速にエクスポートおよびインポートできます
>>: PHP の問題により、Zabbix モニタリングでグラフィカル インターフェイスに中国語の文字化けが発生する問題を解決する方法
この記事では、ユーザーのログイン切り替えを実現するためのVueの具体的なコードを例として紹介します。...
Linux コマンドの学習は、ほとんどの初心者にとって最大の障害です。今日は、Linux システムで...
最近、仕事で問題に遭遇しました。グローバル変数 red_heart があります。これは多くの場所で使...
<canvas> 要素は、クライアント側のベクター グラフィックス用に設計されています。...
Linux でのルーティング設定コマンド1. ホストルーティングを追加する ルートを追加 -host...
目次1. はじめに2. データを消去するいくつかの方法2.1 ref() の使用2.2 スライスの使...
MySQL の運用と保守において、R&D の同僚が 2 つの異なるインスタンスのデータを比較...
公式の Docker レジストリを使用して作成されたウェアハウスでは、イメージを削除してもデフォルト...
MySQL 5.7.27のインストールチュートリアルは以下のように記録され、皆さんと共有されています...
トランザクション分離レベルを確認するMySQL では、'%tx_isolation%'...
JSON は、言語に依存しないテキスト形式を使用する軽量のデータ交換形式で、XML に似ていますが、...
インデックスの2つの主要なカテゴリ使用されるストレージエンジン: MySQL 5.7 InnoDBク...
目次シンボルデータタイプシンボルが表示される理由シンボルの特徴シンボルの応用rbオブジェクトにupメ...
MySQL-8.0.22-winx64のデータベースインストールチュートリアルは参考になります。具体...
vueモバイル端末は、画面上で指をスライドさせる方向を判断します。具体的な内容は次のとおりです。これ...