🕌
Reactのエラーハンドリングを実装する(react native)
ErrorBoundary で検知できないエラーに対応するには
※サーバーサイドレンダリングに関してはここでは扱いません。(react native 実装をしているため。)
React の公式ドキュメントでは以下の通り
error boundary は以下のエラーをキャッチしません:
イベントハンドラ
非同期コード(例:setTimeout や requestAnimationFrame のコールバック)
サーバサイドレンダリング
(子コンポーネントではなく)error boundary 自身がスローしたエラー
つまり、個別でエラーハンドリングが必要な非同期処理や、APi リクエストを ErrorBoundary で一元的に管理したい場合には、工夫が必要ということらしいです。
react-error-boudanry
などの最適化されたライブラリもあるが、こちらが上記の場合のエラーを内部実装で考慮しているかは不明。おそらく、
イベントハンドラー・非同期のエラー
Error Boudanry で非同期エラーを検出するためには、それらのエラーをレンダリングプロセスに組み込む必要があります。
参考
// hooks
export function useErrorHandler(
givenError?: unknown
): (error: unknown) => void {
const [error, setError] = React.useState<unknown>(null);
if (givenError != null) throw givenError;
if (error != null) throw error;
return setError;
}
// ---------------------------------
// component
useEffect(() => {
(async () => {
try {
throw new Error("error");
} catch (error) {
errorHandler(error as Error);
}
})();
}, [errorHandler]);
上記の Hooks と ErrorBoundary を組み合わせることで、非同期で try catch したエラーを一元的にハンドリングすることができるようになりました。
React Native での ErrorBoundary の実装
候補
- react-error-boundanry
- react-native-error-boundary
- ゴリゴリ実装
試してみた結果
react-native-error-boundary
- 自分の環境だけなのか、import⇩ 際の型が合わずエラーとなってしまって、ちょっとめんどくさかった。
import * as ErrorBoundaryModule from "react-native-error-boundary";
import type { Props } from "react-native-error-boundary/lib/ErrorBoundary";
type State = { error: Error | null };
const ErrorBoundary = ErrorBoundaryModule as unknown as React.Component<
Props,
State
>;
- option が、react-error-boundary より少ないので、独自実装が必要
ゴリゴリ実装
- スクラッチで書いていくので、複雑にエラーハンドリングを実装していきたい場合にちょっとめんどくさい
- 例えばでいうと、errorInfo ををどのように外部コンポーネントから参照できるようにするか
- reset を外部から発火させたい場合には errorBoundary を Context 化して、hooks で state を切り替える実装が必要そうであったりなど
react-error-boundary
めっちゃいい
めちゃいいポイント
::message
注意点
上記の記事だと react-error-boudnary を使用すると非同期・イベント内のエラーを自動でハンドリングしてくれそうな理解になるが、そういうわけではないので、独自で上記のようなuseErrorHandler
なりを実装してハンドリングは必要
:::
Discussion