![今のところinput[type=”number”]を使わない方が良い理由と代替案 アイキャッチ](https://www.fourier.jp/storage/blog/post-outline/jLh85zUW8RaWiVlX9MATwpSprFDEYZw5.jpg)
はじめに
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」
と表示されます。
さいごに
props.childrenの値をReactNodeを返す関数にすることで、型付けした上で親コンポーネントから子コンポーネントへpropsを渡すことができるようになりました。
方法としては単純ですが、意外と思いつかなかったりするものではないでしょうか。もしこの方法が必要になりましたらぜひ使用してみてください。