https://qiita.com/nuko-suke/items/fdecac831533c3d8bbf0

こんにちは。ぬこすけです。

皆さんは React でエラー画面を出す時どうしていますか? おそらく、こんな感じで頑張っているんじゃないかと思います。

function MyWidget() {
  const [isError, setIsError] = useState(false);

  useEffect(() => {
    // 何かしらデータを取得する処理
    fetchSomething()
      .then(() => {
        // データの取得に成功した時の処理
      })
      .catch(() => {
        setIsError(true);
      })
  }, [])

  if (isError) {
    return <div>エラーです</div>
  }
  return <div>正常です</div>
}

いたって普通のコードです。 が、コンポーネントごとでこのようなエラーのための処理を書いていくのは手間がかかります。

場合によっては「エラーが起きたらサーバーにエラー情報を送信する」とか増えるとさらに面倒です。

今回は React でもっと楽にエラー画面出せる方法を共有したい と思います!

Error Boundary って知っていますか?

React には Error Boundary という機能があります。

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

Error Boundary とは React 公式ドキュメントの引用文通りです。 コンポーネントでエラーが発生した時に、エラーを補足したり、エラー用の UI を表示できるというわけです。

具体的なコードを見てみましょう。 React の公式サイトのコード例から引用します。

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    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 also log the error to an error reporting service
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

このような ErrorBoundary というクラスコンポーネントがあります。constructorrender の箇所を見ると、どうやらこのコンポーネントはエラーかどうかの状態を保持していて、エラーの場合はエラー用の UI を表示するコンポーネントのようです。

普通のコンポーネントとは違って、 getDerivedStateFromErrorcomponentDidCatch というメソッドがあります。これは一体なんでしょうか?

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

getDerivedStateFromError は子孫コンポーネントで何かエラーが起きた時に呼び出されます 。 React 公式ドキュメントのコード例では、子孫コンポーネントで何かエラーが起きた時に { hasError: true } と状態を更新し、エラー用の UI を表示しています。

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    logErrorToMyService(error, errorInfo);
  }

componentDidCatchgetDerivedStateFromError と同じく 子孫コンポーネントで何かエラーが起きた時に呼び出されますgetDerivedStateFromError との違いは次の 2 点です。