はじめに
今回は、React+Typescript環境でエラーハンドリングについて向き合った結果についてまとめて報告していこうと思います。
どもども!新米フロントエンドエンジニアである龍ちゃんです。エラーハンドリングって大変だなと思っている今日この頃です。注意点です!この記事ではコーディングまでは行わず、事前準備として調べた内容をざっくりとまとめた内容になります。
先に結論としてReactでエラーハンドリング方法について触れておきます。
ここからは、僕の頭の中を図に落とし込んで各項目の説明を挟んでいきます。実装用のメモとして先人たちのブログを掲載しておきます。僕自身もこれからという分野なので一緒にエラーハンドリングの沼におぼれていきましょう。
僕の勉強遷移
はい!勉強遷移をそのままアウトプットしました。今回のこと始まりとしては、エラーハンドリングという単語を知らないところから始まりました。プロダクトに入っていくにつれて、対応事項に「エラーハンドリング」があるとのことで、矢印の流れで調べを進めていきました。
では、React+Typescript環境でのエラーとの向き合いについて順を追って話を進めていきます。これ以降はエラーハンドリングに取り組む理由について考えています。
エラーの原因について考えると、エラーの原因を二つに大別することができます。
- コンポーネントレベルでのエラー
- API通信時におけるデータ取得時エラー
実装を進めていて、すっごく大きく分けて二つです。すべては実装時のバグに帰着するのですが、そのバグをつぶす作業がエラーとの戦いです。
React16以降ではコンポーネントでエラーが発生した場合、真っ白な画面が表示されるようになっています。開発中の画面ではよくある光景ですね。当初の僕も開発者ツールで見ればエラーが表示されているので、開発者ツールを開きっぱなしでした。
リリースした際、真っ白な画面が表示されたら困りますよね?というか開発会社として能力を疑われてしまいますね。つまりユーザーの体験が阻害されるわけです。という訳で、プロダクトに関わるエンジニアはもれなく全員エラーハンドリングに取り組まなければならないのです。
それでは調べた内容の共有を始めていきます。今回は、以下の三つの順番で簡易な解説と学習用リンクを挟んでいきます。
- React標準:ErrorBoundary
- Axios InterSepter
- Suspense + SWRなどのデータフェッチ用ライブラリとErrorBoundary
React標準:ErrorBoundary
こちらは公式のErrorBoundaryのリンク集です。公式で紹介されているだけあるので、使い勝手としてはとてもシンプルです。とりあえず公式のページを張っておきます。注意点としては、以下のエラーはキャッチしないことです。
- イベントハンドラ
- 非同期コード
- サーバーサイドレンダリング
- ErrorBoundary自身がエラーを発生させた場合
ここで気にしてほしいのが「非同期コードのエラーをキャッチできない」という文言です。つまりAPI処理のエラーはキャッチできないとなっています。
ErrorBoundaryは公式のサンプルでもですが、Classメソッド記法で記述されています。関数コンポーネントで書く方法については調べても出てきませんでした。
先ほど非同期コードのエラーをキャッチすることができないといいましたが、調べていくとイベントを登録することでエラーをキャッチする方法にトライされている記事がありました。念のためにまとめておきます。ただエラーがキャッチされるまでラグが発生するので使いどころとしては悩みます。
ErrorBoundaryでは自分でファイルを作成してカスタマイズする必要があり、若干コストが高いです。そのコストを下げてくれるライブラリとして「react-error-boundary」があります。参考にしたサイトを以下にまとめておきます。
こちらを使うことで記述量としては、少なく記述することができます。二番目の記事の「piyoko」さんにはめちゃめちゃお世話になっています。
まとめとしては、
- Reactコンポーネントで発生したエラーに関しては問題なくキャッチすることができ、画面を差し替えることができる。
- 非同期処理(API処理)のエラーハンドリングを行うには不十分である。
ということになります。
Axios InterSeptor
こちらは先ほど記述したErrorBoundaryでキャッチできなかった、非同期処理(API処理)のエラーをキャッチする方法についての記事を紹介します。Axiosはデータ呼び出しを容易にするライブラリです。InterSeptorでは、requestやresponseに共通の処理を挟み込むことができます。こちらの機能を利用して、responseの共通処理でエラーハンドリングを行う方法があります。イメージとしては以下の図になります。
構築のためのリンクを以下にまとめておきます。
- 公式のAxios
- React axios インターセプターでフックを使えるようにする
- Axiosしているならエラーハンドリングはinterceptors一択
- 【React】axiosエラーハンドリング共通化
こちらのリンクで特に参考にしたのは二番目の記事です。もろ「piyoko」さんの記事です。
前述のErrorBoundaryと併用して作成することで、非同期のエラーとコンポーネントのエラーをどちらもキャッチすることができます。
Suspense + データフェッチ用ライブラリ
この項目は実験的だそうです。まだまだ情報としてもあまり出てきていないですね。とりあえず調べてわかったことは、以下になります。
- Suspenceを使用するとLoadingが簡単に出せる
- データ取得用ライブラリ(SWR・ReactQuery)などを使用すると良い
- データ取得用ライブラリでのエラーハンドリングという選択肢もある
このSuspenseを介することで、エラーをReact内でのエラーとして出すことができます。まだまだ調べている段階なので難しいですね。
- React公式:Suspenseのエラーハンドリング
- ReactのSuspenseを使った非同期処理のエラーハンドリング フロントエンドLT会
- React18の新機能 Suspense機能を使ってローディング画面とエラー画面を表示してみよう
おわりに
エラーハンドリングはどこで管理するかといった問題がありますね。ざっくりと調べただけでも3パターンありますね。React18から新しい選択肢が増えたようですが、調べると新しいキーワードをゲットしましたね。「SWR」と「ReactQuery」はデータ取得用ライブラリですが、情報の再取得や情報の取得部分に関するもろもろの処理をいい感じにやってくれるようです。
エラーハンドリングの検証では以下の二つの記事を予定しています。
- 標準のエラーハンドリングとreact-error-boundaryを用いたコンポーネント差し替え
- Axios Interseptorを用いた非同期処理のエラーハンドリングを用いたコンポーネント差し替え
その検証・記事が終了したら「SWR」と「ReactQuery」などのデータ取得用ライブラリについての検証・記事まとめを行いと思います。
以降にまとめた際のリンクを追記していきますね。