エラー処理
JavaScript は柔軟なインタプリタ型言語であるため、実行時にエラーが発生する可能性(そして容易さ)があります。予期しないシナリオの結果であろうと、私たちが書いたコードの間違いであろうと、エラーを監視し、何らかのリカバリまたは例外処理を実装できることが重要です。
Preact では、これを行う方法は、エラーをキャプチャして状態として保存することです。これにより、コンポーネントは予期しないレンダリングまたは壊れたレンダリングをインターセプトし、フォールバックとして別のものをレンダリングするように切り替えることができます。
エラーを状態に変換する
エラーをキャプチャして状態に変換するには、componentDidCatch
と getDerivedStateFromError
の 2 つの API を使用できます。機能的には似ており、どちらもクラスコンポーネントに実装できるメソッドです。
componentDidCatch は Error
引数を渡され、その Error に対してケースバイケースで何をすべきかを決めることができます。フォールバックまたは代替ツリーをレンダリングするために this.setState()
を呼び出すことができます。これにより、エラーが「キャッチ」され、処理済みとしてマークされます。または、メソッドは単にエラーをどこかにログし、未処理のまま(クラッシュする)にすることができます。
getDerivedStateFromError は、Error
を渡され、状態更新オブジェクトを返す静的メソッドです。これは setState()
を介してコンポーネントに適用されます。このメソッドは常に状態の変化を生み出し、そのコンポーネントの再レンダリングにつながるため、常にエラーを処理済みとしてマークします。
次の例は、いずれかのメソッドを使用してエラーをキャプチャし、クラッシュする代わりに例外メッセージを表示する方法を示しています。
import { Component } from 'preact'
class ErrorBoundary extends Component {
state = { error: null }
static getDerivedStateFromError(error) {
return { error: error.message }
}
componentDidCatch(error) {
console.error(error)
this.setState({ error: error.message })
}
render() {
if (this.state.error) {
return <p>Oh no! We ran into an error: {this.state.error}</p>
}
return this.props.children
}
}
上記のコンポーネントは、Preact アプリケーションでエラー処理が実装される一般的な例であり、多くの場合、エラーバウンダリ と呼ばれます。
ネストとエラーのバブリング
Preact が仮想 DOM ツリーをレンダリングしているときに発生したエラーは、DOM イベントと同様に「バブルアップ」します。エラーが発生したコンポーネントから始まり、ツリー内の各親コンポーネントはエラーを処理する機会が与えられます。
その結果、componentDidCatch
を使用して実装した場合、エラーバウンダリをネストできます。コンポーネントの componentDidCatch()
メソッドが setState()
を呼び出さない場合、エラーは、setState()
を呼び出す componentDidCatch
メソッドを持つコンポーネントに到達するまで、仮想 DOM ツリーをバブルアップし続けます。
試してみましょう!
エラー処理の知識をテストするために、単純な App コンポーネントにエラー処理を追加してみましょう。App の奥深くにあるコンポーネントの 1 つが特定のシナリオでエラーをスローする可能性があり、フレンドリーなメッセージを表示して予期しないエラーが発生したことをユーザーに伝えるために、このエラーをキャッチしたいと考えています。