カテゴリ: React 更新日: 2026/02/02

Reactのカスタムフックでエラー状態を管理する方法!初心者でもわかるAPIエラーハンドリング

カスタムフックでエラー状態を管理する方法
カスタムフックでエラー状態を管理する方法

先生と生徒の会話形式で理解しよう

生徒

「ReactでAPIを呼び出すときに、失敗したらどうなるんですか?」

先生

「良い質問ですね。API通信は常に成功するとは限りません。サーバーが落ちていたり、ネットワークが不安定だったりすると失敗することがあります。」

生徒

「そういうときって、画面はどうなるんですか?」

先生

「何も準備していないとエラーが出ても真っ白になってしまいます。そこで『エラー状態』を管理して、ユーザーにわかりやすいメッセージを表示することが大事なんです。」

1. エラー状態とは?

1. エラー状態とは?
1. エラー状態とは?

エラー状態とは、APIからデータを取ってくるときに「失敗しました」とアプリが認識する状態のことです。例えば、天気予報アプリでデータが取得できないときに「データの取得に失敗しました」と表示されるのを見たことがあるでしょう。それがまさにエラー状態の管理です。

プログラミング未経験の方にわかりやすく例えると、郵便を頼んだのに住所が間違っていて届かないことがありますよね。そのときに「住所が違います」と通知してくれるのがエラー状態の役割です。

2. Reactでエラーを管理する必要性

2. Reactでエラーを管理する必要性
2. Reactでエラーを管理する必要性

ReactでAPIを使うとき、ただ結果だけを表示するのでは不十分です。なぜなら通信は失敗することがあるからです。もしエラーを無視してしまうと、ユーザーは「動かない」「壊れている」と感じてしまいます。

エラー状態をきちんと管理して「ネットワークエラーが発生しました」「もう一度試してください」と表示できれば、ユーザーは安心して使うことができます。これはアプリの信頼性を高めるためにとても重要なことです。

3. カスタムフックでエラーを管理する基本

3. カスタムフックでエラーを管理する基本
3. カスタムフックでエラーを管理する基本

毎回同じようにuseStateuseEffectでエラー処理を書くのは大変です。そこで「カスタムフック」を作ってエラー処理をまとめてしまいましょう。そうすれば、再利用できて開発が楽になります。


import { useState, useEffect } from "react";

function useFetchWithError(url) {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch(url)
      .then((res) => {
        if (!res.ok) {
          throw new Error("サーバーエラーが発生しました");
        }
        return res.json();
      })
      .then((json) => setData(json))
      .catch((err) => setError(err.message));
  }, [url]);

  return { data, error };
}

export default useFetchWithError;

このカスタムフックでは、エラーが起きたときにsetErrorで状態を保存します。これで呼び出し元のコンポーネントから「エラーがあるかどうか」を判定できるようになります。

4. 作ったカスタムフックを使ってみる

4. 作ったカスタムフックを使ってみる
4. 作ったカスタムフックを使ってみる

次に、このカスタムフックを実際にコンポーネントで使ってみましょう。


import React from "react";
import useFetchWithError from "./useFetchWithError";

function App() {
  const { data, error } = useFetchWithError("https://api.example.com/items");

  if (error) return <p>エラーが発生しました: {error}</p>;

  if (!data) return <p>データを取得中です...</p>;

  return (
    <div>
      <h1>商品一覧</h1>
      <ul>
        {data.map((item) => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;
(通信に失敗すると「エラーが発生しました」と表示されます。成功した場合は「商品一覧」が表示されます)

5. エラー状態をわかりやすく伝える工夫

5. エラー状態をわかりやすく伝える工夫
5. エラー状態をわかりやすく伝える工夫

ただ「エラー」と出すだけでは不親切です。例えば「ネットワークに接続できません」「サーバーが混雑しています」など、状況に応じたメッセージを表示することでユーザーは次に何をすればいいか理解できます。

さらに、再読み込みボタンを用意して「もう一度試す」ことができるようにすると、使いやすさがぐんと上がります。これは初心者でもすぐに取り入れられる工夫です。

6. ローディングとエラーを組み合わせる

6. ローディングとエラーを組み合わせる
6. ローディングとエラーを組み合わせる

実際のアプリでは、データ取得中とエラー発生後を両方管理する必要があります。そこで、ローディングとエラーを一緒に扱えるカスタムフックを作ると便利です。


import { useState, useEffect } from "react";

function useFetchWithLoadingAndError(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);
    fetch(url)
      .then((res) => {
        if (!res.ok) {
          throw new Error("エラーが発生しました");
        }
        return res.json();
      })
      .then((json) => {
        setData(json);
        setLoading(false);
      })
      .catch((err) => {
        setError(err.message);
        setLoading(false);
      });
  }, [url]);

  return { data, loading, error };
}

export default useFetchWithLoadingAndError;

これで「読み込み中」「成功」「失敗」をきちんと分けて表示できるようになります。実際のアプリ開発ではこの形がよく使われます。

7. エラー管理をするメリット

7. エラー管理をするメリット
7. エラー管理をするメリット

エラー状態をきちんと管理することで、ユーザーにとって安心できるアプリを作れます。もし「真っ白な画面」が出るだけなら、不安になってアプリを閉じてしまうかもしれません。

「エラーが発生しました」と表示されるだけで「自分の操作が間違っていない」と理解できるので、信頼感が高まります。Reactのカスタムフックを活用すれば、この仕組みを簡単に実装できるのです。

まとめ

まとめ
まとめ

ここまで、Reactのカスタムフックを使ったエラー状態の管理方法について詳しく解説してきました。Webアプリケーションにおいて、API通信は切っても切り離せない重要な要素ですが、それと同時に「通信の失敗」も避けては通れない現実です。フロントエンド開発者の役割は、単にデータを画面に表示するだけでなく、予期せぬエラーが発生した際にユーザーを迷わせないための「道しるべ」を作ることにあると言っても過言ではありません。

Reactにおけるエラーハンドリングの重要ポイント

今回の内容をおさらいすると、エラー管理において特に意識すべき点は以下の3つです。

  • ユーザー体験(UX)の向上: エラー時に画面が真っ白になるのを防ぎ、何が起きたのかを正確に伝えます。
  • コードの再利用性: カスタムフック(useFetch等)にロジックをまとめることで、複数のコンポーネントで同じエラー処理を使い回せます。
  • 状態の明確化: 「ローディング中」「成功」「エラー」の3つの状態を定義することで、条件分岐がシンプルになり、バグの少ないコードになります。

実践的なカスタムフックの応用例

さらに実戦で役立つテクニックとして、エラーが発生した際にユーザーが自ら「再試行」できる仕組みを組み込んだコードを紹介します。このように、単にエラーを表示するだけでなく、次のアクションを促すのがモダンなフロントエンド開発のスタンダードです。


import { useState, useEffect, useCallback } from "react";

/**
 * 再試行機能付きのカスタムフック
 */
function useFetchWithRetry(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [refetchIndex, setRefetchIndex] = useState(0);

  // 再取得をトリガーする関数
  const refetch = useCallback(() => {
    setRefetchIndex((prev) => prev + 1);
  }, []);

  useEffect(() => {
    let isMounted = true;
    setLoading(true);
    setError(null);

    fetch(url)
      .then((res) => {
        if (!res.ok) {
          throw new Error(`エラーコード: ${res.status} - データの取得に失敗しました`);
        }
        return res.json();
      })
      .then((json) => {
        if (isMounted) {
          setData(json);
          setLoading(false);
        }
      })
      .catch((err) => {
        if (isMounted) {
          setError(err.message);
          setLoading(false);
        }
      });

    return () => {
      isMounted = false;
    };
  }, [url, refetchIndex]);

  return { data, loading, error, refetch };
}

export default useFetchWithRetry;

このフックを使えば、コンポーネント側で「リトライボタン」を簡単に実装できます。プログラムを組む際は、常に「もし失敗したらどうするか?」という守りの姿勢を持つことが、プロフェッショナルへの第一歩です。

(refetch関数を呼び出すことで、画面をリロードせずにAPIから最新データを再度取得し直すことができます)

SEOとアクセシビリティへの配慮

エラーメッセージを実装する際は、SEOやアクセシビリティの観点も忘れてはいけません。例えば、エラー文言には role="alert" を付与したり、検索エンジンがコンテンツの不備を正しく認識できるように適切なHTMLタグを選択したりすることが大切です。 JavaScriptやTypeScriptを駆使して、堅牢なアプリケーションを構築していきましょう。Next.jsなどのフレームワークを使用している場合でも、このカスタムフックの考え方は共通して活用できる強力な武器になります。

先生と生徒の振り返り会話

生徒

「先生、カスタムフックを使うとエラー処理がすごくスッキリしますね!今まではコンポーネントの中に useState がたくさん並んでいて、何が何だか分からなくなっていました。」

先生

「そうでしょう。ロジックを切り出すことで、コンポーネントは『見た目』に集中できるようになります。これがReactらしい、宣言的なプログラミングの大きなメリットなんですよ。」

生徒

「今回の refetch の仕組みも面白いです。ボタンを押すだけでデータをもう一回取りにいけるのは、ユーザーにとっても親切ですね。でも、エラーメッセージの内容って、どんな風に決めるのが一番いいんでしょうか?」

先生

「鋭いですね。理想的なのは、エラーの原因を切り分けることです。例えば『404』なら『ページが見つかりません』、『500』なら『サーバーが混み合っています』といった具合です。技術的な用語をそのまま出すのではなく、ユーザーが次に何をすべきかを伝える言葉選びを意識してみてください。」

生徒

「なるほど。ただエラーと言うんじゃなくて、『通信環境を確認してください』とか具体的なアドバイスを添えるイメージですね。さっそく自分のポートフォリオサイトにも導入してみます!」

先生

「その意気です。API通信があるところにエラー管理あり。どんな時でも安定して動くアプリを目指して、一歩ずつ進んでいきましょう。Reactのスキルが一段階上がった証拠ですよ。」

カテゴリの一覧へ
新着記事
New1
React
Reactコンポーネントの再利用と分割を完全マスター!初心者でもわかるコンポーネント設計
New2
React
ReactでAxiosインターセプターの使い方を完全ガイド!初心者でもわかるリクエストとレスポンスの処理方法
New3
React
JSXの書き方!初心者でもわかるReactタグと属性の基本ルール解説
New4
React
ReactとDockerを使った開発環境構築の基本を徹底解説!初心者でもわかるReactとDockerの連携方法
人気記事
No.1
Java&Spring記事人気No1
React
ReactでonChangeイベントを使ってフォーム入力値を管理する方法を初心者向けに解説
No.2
Java&Spring記事人気No2
React
Reactのイベントハンドリングのアンチパターンまとめ!初心者でもわかる注意点
No.3
Java&Spring記事人気No3
React
ReactとTypeScriptの環境構築をやさしく解説!Viteとtsconfigの設定も丁寧に紹介
No.4
Java&Spring記事人気No4
React
Reactのカスタムフックの作り方を完全ガイド!再利用可能なロジックを切り出す仕組み
No.5
Java&Spring記事人気No5
React
ReactでFetch APIのローディング状態を管理する方法|初心者にもわかる解説
No.6
Java&Spring記事人気No6
React
ReactのuseStateとuseEffectでよくあるエラーと解決方法ガイド!初心者でもわかるReactフック
No.7
Java&Spring記事人気No7
React
create-react-appでReactプロジェクトを作成する手順を初心者向けに完全解説!
No.8
Java&Spring記事人気No8
React
Reactでファイルアップロードを実装する方法を解説!Fetch APIで画像やPDFを送る仕組みを初心者向けに紹介