2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.jsのError Boundaryについて

Posted at

Error Boundaryとは

Reactドキュメントより以下のようにありました。

error boundary は自身の子コンポーネントツリーで発生した JavaScript エラーをキャッチし、エラーを記録し、クラッシュしたコンポーネントツリーの代わりにフォールバック用の UI を表示する React コンポーネントです。

公式のNext.jsのError Boundaryについて

Next.jsのError BoundaryのページではError Boundaryについて解説してあります。

簡単に説明するとError Boundaryというコンポーネントを作成し、それを_app.jsxでwrapしてくださいということです。

ErrorBoundary.jsx
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
_app.jsx
// 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;
_app.tsx
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をサポートしていることです。

参考文献

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?