はじめに
React.jsでエラー処理を行う場合、ErrorBoundaryという選択肢があるかと思います。
ErrorBoundaryを使用する際に、フォールバックコンポーネントに型付け
した上でエラー情報を渡すにはどうすればよいか、悩んだことがあったので、今回記事を執筆しました。
私の場合はErrorBoundaryを使用する際に必要となりましたが、その他の場合でも活用できるので、最後まで読んでいただけましたら幸いです。
※本記事はErrorBoundaryについて理解されている方を対象にしています。本記事ではErrorBoundaryについての説明はしませんので、わからない方は、記事を読む前に公式ドキュメントを一読ください。
実装
早速実装していきます。まずはエラーを受け取って、エラーメッセージを表示するDisplayErrorMessage
コンポーネントを作成します。
動作確認をしやすくするため、「Reset Error」
ボタンを設置します。このボタンを押すとエラーをリセットできます。
const DisplayErrorMessage = (
{ error, resetError }: { error: Error, resetError: () => void }
) => (
<>
<h1>{error.message}</h1>
<button onClick={resetError}>{'Reset Error'}</button>
</>
);
次にエラーをスローするThrowError
コンポーネントを作成します。 こちらも動作確認をしやすくするため、「Throw Error」
ボタンを設置します。このボタンを押すことでエラーをスローします。
const ThrowError = () => {
const [shouldThrow, setShouldThrow] = React.useState(false);
if(shouldThrow) {
throw new Error('Error');
}
return (
<>
<h1>No Error</h1>
<button onClick={() => setShouldThrow(true)}>{'Throw Error'}</button>
</>
);
}
最後にErrorBoundary
コンポーネントを作成します。これで必要なコンポーネントが揃いました。
ここで重要なのが、エラーが発生した際に表示されるフォールバックコンポーネントを、関数を実行しレンダリングできるようにすることです。
そうすることで関数の引数からエラーを渡し、そのエラーをコンポーネントのpropsに設定することが可能となります。
import React from 'react';
type FallbackFunc = (error: Error, resetError: () => void) => React.ReactNode;
type ErrorBoundaryProps = {
fallback?: React.ReactNode | FallbackFunc
children?: React.ReactNode;
};
type ErrorBoundaryState = {
error: Error | null;
};
class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
state: ErrorBoundaryState = { error: null };
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
this.setState({ error });
}
render() {
if (this.state.error) {
return typeof this.props.fallback === 'function'
? this.props.fallback(this.state.error, () => this.setState({ error: null }))
: this.props.fallback;
}
return this.props.children
}
}
ErrorBoundary のfallback
プロパティにerror
とresetError
を受け取り、返り値にそれらをpropsに設定したDisplayErrorMessage
コンポーネントを返すようにしています。
const App = () => (
<ErrorBoundary
fallback={(error, resetError) => <DisplayErrorMessage error={error} resetError={resetError} />}
>
<ThrowError />
</ErrorBoundary>
);
以下が実際に動作するデモになります。
「Throw Error」
ボタンをクリックすることで、「No Error」
と表示されていた箇所が「Error」
に変わることが確認できるかと思います。
また、「Reset Error」
ボタンをクリックすることで、再度「No Error」
と表示されます。
See the Pen A Pen by FOURIER Inc. by FOURIER Inc. (@fourier-inc) on CodePen.
さいごに
props.childrenの値をReactNodeを返す関数にすることで、型付けした上で親コンポーネントから子コンポーネントへpropsを渡すことができるようになりました。
方法としては単純ですが、意外と思いつかなかったりするものではないでしょうか。もしこの方法が必要になりましたらぜひ使用してみてください。
新しいメンバーを募集しています
Ohashi / Engineer
主にLaravelなどのバックエンドを中心にサーバー周りも担当しています。 目標は腕周り40cm 越え。