React Native
with
Error Boundary
自己紹介
公式ページ
Error Boundaryとは
error boundary は自身の子コンポーネントツリーで発生した JavaScript エラーをキャッチし、エラーを記録し、クラッシュしたコンポーネントツリーの代わりにフォールバック用の UI を表示する React コンポーネントです。error boundary は配下のツリー全体のレンダー中、ライフサイクルメソッド内、およびコンストラクタ内で発生したエラーをキャッチします。
Home画面でのエラーが発生した際の例
import React from 'react';
import { View, Text } from 'react-native';
const Fallback = () => (
<View>
<Text>現在正常に動作していないようです。</Text>
</View>
);
export default class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError(e) {
return { hasError: true };
}
render() {
const { children } = this.props;
const { hasError } = this.state;
if (hasError) return <Fallback />;
return children;
}
}
Error Boundary Component
注意
error boundary は以下のエラーをキャッチしません:
- イベントハンドラ
- 非同期コード
- サーバーサイドレンダリング
- error boundary 自身がスローしたエラー
<Button
onPress={() => {
// throw new Error('error');
}}
title="cause an error"
/>
イベントハンドラでのキャッチされない例
Error Boundaryに必ずキャッチしてもらうには?
import React, { useState } from 'react';
import { View, Button } from 'react-native';
const HandledErrorComponent = () => {
const [error, setError] = useState(false);
if (error) {
throw new Error('error');
}
return (
<View>
<Button
onPress={() => {
setError(true);
}}
title="cause an error"
/>
</View>
);
}
import React, { useState, useEffect } from 'react';
import { View } from 'react-native';
const HandledErrorComponent = () => {
const [error, setError] = useState(false);
useEffect(() => {
(async () => {
try {
await fetch('call api');
} catch (e) {
setError(true);
}
})();
}, []);
if (error) {
throw new Error('error');
}
return (
<View>
{/* show results */}
</View>
);
}
stateでエラーをハンドリングしてthrowする。try catchを駆使する。
Error Boundaryまとめ
- 自分で用意したエラーキャッチ用のコンポーネント
- キャッチできないパターンがあるので注意
- エラーが起きそうなところはtry catchで囲み、stateでエラーを拾ってthrowすること
- Error Boundaryで拾えないエラーが起きた場合、コンポーネントツリーがアンマウントされる(画面真っ白になりうる)
- Error Boundaryの置き場所、使い方は開発者依存。トップに1つ置くもよし、複数置くもよし。最も近いError Boundaryにエラーが伝搬される
Thank You
React Native with Error Boundary
By Teruhisa Yamamoto
React Native with Error Boundary
- 273