Error Boundaryとは
Reactドキュメントより以下のようにありました。
error boundary は自身の子コンポーネントツリーで発生した JavaScript エラーをキャッチし、エラーを記録し、クラッシュしたコンポーネントツリーの代わりにフォールバック用の UI を表示する React コンポーネントです。
公式のNext.jsのError Boundaryについて
Next.jsのError BoundaryのページではError Boundaryについて解説してあります。
簡単に説明するとError Boundaryというコンポーネントを作成し、それを_app.jsx
でwrapしてくださいということです。
class ErrorBoundary extends React.Component {
constructor(props) {
super(props)
// Define a state variable to track whether is an error or not
this.state = { hasError: false }
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI
return { hasError: true }
}
componentDidCatch(error, errorInfo) {
// You can use your own error logging service here
console.log({ error, errorInfo })
}
render() {
// Check if the error is thrown
if (this.state.hasError) {
// You can render any custom fallback UI
return (
<div>
<h2>Oops, there is an error!</h2>
<button
type="button"
onClick={() => this.setState({ hasError: false })}
>
Try again?
</button>
</div>
)
}
// Return children components in case of no error
return this.props.children
}
}
export default ErrorBoundary
// Import the ErrorBoundary component
import ErrorBoundary from '../components/ErrorBoundary'
function MyApp({ Component, pageProps }) {
return (
// Wrap the Component prop with ErrorBoundary component
<ErrorBoundary>
<Component {...pageProps} />
</ErrorBoundary>
)
}
export default MyApp
私もこれで実装しようとしたのですが、エラー文が全部取得できなかったり
、挙動が狙ったようにならないため断念しました。
あとは、TypeScript
のサンプルが全然ないことです。(あるにはあります)
react-use-error-boundaryの導入
Next.jsのエラーハンドリングはIssueでも議論されていることを知り、そこで react-use-error-boundary
というライブラリが紹介されていたので使用してみたらとても良かったので紹介します。
インストール
yarn add react-use-error-boundary
使用方法
エラーをキャッチしたいコンポーネントでwithErrorBoudnary()
をラップします。
つまり以下のような_app.tsxの場合
import type { AppProps } from 'next/app';
const App = ({ Component, pageProps }: AppProps) => {
return (
<Component {...pageProps} />
);
};
export default App;
import type { AppProps } from 'next/app';
import { useErrorBoundary, withErrorBoundary } from 'react-use-error-boundary';
import sendToMyService from '@/utils/sentry';
const App = withErrorBoundary(({ Component, pageProps }: AppProps) => {
const [error, resetError] = useErrorBoundary(async (error) => {
sendToMyService(error);
});
return (
<Component {...pageProps} />
);
});
export default App;
このようにすればOKです。エラーメッセージはerrorに格納されています。
あとはnodemailerやsentryなどに送信すればOKです。
また、エラーをリセットしたい場合はresetError関数が呼べるのでエラーハンドリングが終わったタイミングで呼び出すことができます。
また、errorで条件分岐すればエラー画面に飛ばすこともできます。
import type { AppProps } from 'next/app';
import { useErrorBoundary, withErrorBoundary } from 'react-use-error-boundary';
import sendToMyService from '@/utils/sentry';
const App = withErrorBoundary(({ Component, pageProps }: AppProps) => {
const [error, resetError] = useErrorBoundary(async (error) => {
sendToMyService(error);
});
if (error) {
return (
<>ERROR PAGE</>
)
}
return (
<Component {...pageProps} />
);
});
export default App;
このライブラリの良い点
良かったことはエラーハンドリングも関数コンポーネントでかけること、いちいちErrorBoudaryを書かなくていいこと、TypeScriptをサポートしていることです。
参考文献