カテゴリ: React 更新日: 2026/01/08

ReactでAxiosローディング状態を管理する方法を完全ガイド!初心者でもわかる非同期通信の基本

Axiosでローディング状態を管理する方法
Axiosでローディング状態を管理する方法

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

生徒

「ReactでAxiosを使ってデータを取ってくるとき、画面が止まっているように見えることがあります。どうすればわかりやすくできますか?」

先生

「それはローディング状態を管理する必要があります。ユーザーに『今データを読み込み中です』と見せる仕組みですね。」

生徒

「なるほど!それならボタンを押しても無反応に感じなくなりますね。」

先生

「その通りです。ReactとAxiosでのローディング管理を一緒にやってみましょう!」

1. ローディング状態とは?

1. ローディング状態とは?
1. ローディング状態とは?

ローディング状態とは、非同期処理の実行中に「いまデータを読み込んでいます」とユーザーへ伝えるための状態です。 ReactでAxiosなどを使って通信を行う場合、サーバーからの返答を待つ時間が必ず発生します。 その間に何も表示されていないと、ユーザーは操作が受け付けられていないように感じてしまいます。

そのため、ローディング状態を用意して画面表示を切り替えることで、 アプリが正常に動作していることを分かりやすく伝えられます。 これは見た目の問題だけでなく、ユーザーの安心感や操作ミス防止にもつながる重要な考え方です。


import React, { useState } from "react";

function LoadingSample() {
  const [loading, setLoading] = useState(false);
  const [message, setMessage] = useState("");

  const startLoading = () => {
    setLoading(true);
    setTimeout(() => {
      setMessage("データの読み込みが完了しました");
      setLoading(false);
    }, 2000);
  };

  return (
    <div>
      <button onClick={startLoading} disabled={loading}>
        {loading ? "読み込み中..." : "処理を開始"}
      </button>
      {message && <p>{message}</p>}
    </div>
  );
}

export default LoadingSample;
(ボタンを押すと「読み込み中...」と表示され、少し待つと「データの読み込みが完了しました」と表示が切り替わります)

このように、ローディング状態を使うことで、 処理の開始から完了までの流れをユーザーが自然に理解できるようになります。 Reactで非同期通信を扱う際は、まずこのローディング状態の考え方をしっかり押さえておくことが大切です。

2. Reactでローディング状態を管理する基本

2. Reactでローディング状態を管理する基本
2. Reactでローディング状態を管理する基本

Reactでローディング状態を管理する基本はとてもシンプルで、useStateloadingのような真偽値の状態を用意します。 通信やデータ取得などの処理が「始まったらtrue」、処理が「終わったらfalse」に切り替えるだけです。 これだけで、読み込み中の表示を出したり、一覧を表示したりと、画面の見せ方を分かりやすく整理できます。

特に初心者のうちは「どのタイミングで画面が変わるのか」を意識すると理解が早いです。 loadingtrueの間は読み込み中のメッセージを表示し、falseになったら取得したデータを表示する、という流れにすると迷いません。 まずはこの型を覚えておくと、Reactの非同期通信やAPI連携でも応用しやすくなります。


import React, { useState, useEffect } from "react";
import axios from "axios";

function App() {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(true);

    axios
      .get("https://jsonplaceholder.typicode.com/users")
      .then((res) => {
        setData(res.data);
      })
      .catch(() => {
        console.error("エラーが発生しました");
      })
      .finally(() => {
        setLoading(false);
      });
  }, []);

  if (loading) {
    return <div>読み込み中です...</div>;
  }

  return (
    <ul>
      {data.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

export default App;
データ取得中は「読み込み中です...」と表示され、終わるとユーザーの名前一覧が表示されます。

ここでのポイントは、ローディング中に「結果を表示しない」ように分岐している点です。 この分岐があるだけで、画面の状態がはっきりし、ユーザーも状況を理解しやすくなります。 まずはloadingの切り替えと表示の分岐をセットで覚えるのがおすすめです。

3. finallyで確実にローディングを終了する

3. finallyで確実にローディングを終了する
3. finallyで確実にローディングを終了する

Axiosではfinallyを使うと、通信が成功した場合も失敗した場合も、最後に必ず実行したい処理をひとまとめにできます。 ローディング管理で一番怖いのは「エラーが起きたときにloadingを戻し忘れて、ずっと読み込み中の表示が残る」ことです。 finallysetLoading(false)を書いておけば、どんな結果でも必ずローディングを終了できるので安心です。

初心者の方は、thenは「うまくいったとき」、catchは「失敗したとき」、そしてfinallyは「最後に必ずやること」と覚えると理解しやすいです。 画面の表示切り替えやボタンの無効化など、ローディングに関わる後片付けはfinallyにまとめるのが基本になります。


import React, { useState } from "react";
import axios from "axios";

function FinallySample() {
  const [loading, setLoading] = useState(false);
  const [text, setText] = useState("");

  const fetchOnce = () => {
    setLoading(true);

    axios.get("https://jsonplaceholder.typicode.com/posts/1")
      .then((res) => {
        setText(res.data.title);
      })
      .catch(() => {
        setText("通信に失敗しました");
      })
      .finally(() => {
        // 成功でも失敗でも、最後に必ずローディングを終了する
        setLoading(false);
      });
  };

  return (
    <div>
      <button onClick={fetchOnce} disabled={loading}>
        {loading ? "読み込み中..." : "取得する"}
      </button>
      {text && <p>{text}</p>}
    </div>
  );
}

export default FinallySample;
(ボタンを押すと「読み込み中...」に切り替わり、通信が成功するとタイトルが表示され、失敗しても最後に読み込み中表示が消えます)

このように、ローディングを終了する処理をfinallyに置いておくと、 「成功したときだけ戻る」「失敗したときに戻らない」といったミスを防ぎやすくなります。 まずはローディング管理ではfinallyをセットで使う、という感覚を身につけるのがおすすめです。

4. ボタン操作とローディング管理

4. ボタン操作とローディング管理
4. ボタン操作とローディング管理

実際のアプリでは、ボタンを押してデータを取得することも多いです。そのときも同じようにローディング状態を管理します。ボタンを押した直後は「読み込み中...」を表示し、終わったら結果を出します。


import React, { useState } from "react";
import axios from "axios";

function FetchButton() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);

  const fetchData = () => {
    setLoading(true);
    axios.get("https://jsonplaceholder.typicode.com/posts/1")
      .then(res => setData(res.data))
      .catch(() => setData({ title: "エラーが発生しました" }))
      .finally(() => setLoading(false));
  };

  return (
    <div>
      <button onClick={fetchData} disabled={loading}>
        {loading ? "読み込み中..." : "データを取得"}
      </button>
      {data && <div>{data.title}</div>}
    </div>
  );
}

export default FetchButton;
読み込み中はボタンが「読み込み中...」となり、クリックできなくなります。処理が終わると結果が表示されます。

5. ローディング中のUIを工夫する

5. ローディング中のUIを工夫する
5. ローディング中のUIを工夫する

単純に「読み込み中...」と表示するだけでもよいですが、ユーザー体験を向上させるために以下の工夫もよく使われます。

  • スピナー(ぐるぐる回るアイコン)を表示する
  • スケルトンスクリーン(灰色の枠を表示して仮のUIを見せる)
  • ボタンを無効化して二重クリックを防ぐ

これにより、アプリが「固まっている」のではなく「処理中」であることが直感的に伝わります。

6. 実務での注意点

6. 実務での注意点
6. 実務での注意点

実際の開発でAxiosのローディング管理を行うときは、以下の点に注意するとよいです。

  • 複数のリクエストが同時に走る場合、それぞれのローディング状態を個別に管理する
  • 大きなアプリではReduxやReact Queryを使って共通的にローディング状態を扱う
  • ローディングが長引く場合は「しばらくお待ちください」などユーザーが安心できる工夫をする

こうした工夫を積み重ねることで、使いやすく信頼できるReactアプリを作れるようになります。

まとめ

まとめ
まとめ

ReactとAxiosにおけるローディング状態管理の振り返り

この記事では、ReactでAxiosを使って非同期通信を行う際に欠かせない「ローディング状態の管理」について、 初心者の方にも理解しやすい形で順を追って解説してきました。 非同期通信は、データの取得や送信に時間がかかる処理であり、その間に何も表示されていないと、 ユーザーは「画面が止まった」「操作できない」と感じてしまいます。 その不安を取り除くために重要なのが、ローディング状態を正しく管理し、今どんな状況なのかを画面上で伝えることです。

ReactではuseStateを使ってローディング用の状態を用意し、 通信の開始時にtrue、終了時にfalseへ切り替えることで、 シンプルかつ分かりやすくローディング管理ができます。 特にAxiosのfinallyを使うことで、通信が成功しても失敗しても必ずローディングを終了できるため、 「読み込み中のまま止まる」といったトラブルを防ぐことができます。

また、ボタン操作と組み合わせることで、ユーザーが操作した結果として通信が始まったことを明確に伝えられます。 読み込み中はボタンを無効化したり、文言を切り替えたりすることで、 二重クリックを防ぎつつ、現在の状態を直感的に理解してもらえるようになります。 こうした細かい配慮の積み重ねが、使いやすいReactアプリにつながります。

ローディング管理を意識したシンプルなサンプル構成


import React, { useState } from "react";
import axios from "axios";

function SimpleLoadingSample() {
  const [message, setMessage] = useState("");
  const [loading, setLoading] = useState(false);

  const fetchData = () => {
    setLoading(true);
    axios.get("https://jsonplaceholder.typicode.com/posts/1")
      .then(res => setMessage(res.data.title))
      .catch(() => setMessage("データの取得に失敗しました"))
      .finally(() => setLoading(false));
  };

  return (
    <div>
      <button onClick={fetchData} disabled={loading}>
        {loading ? "読み込み中..." : "データ取得"}
      </button>
      {message && <p>{message}</p>}
    </div>
  );
}

export default SimpleLoadingSample;
ボタンを押すと「読み込み中...」と表示され、処理が終わると取得したデータ内容が画面に表示されます。

このような構成にしておくことで、ローディング状態・データ表示・エラー時の表示を ひとつの流れとして整理できます。 初心者のうちは難しく考えず、「通信が始まったらローディングを表示し、終わったら必ず消す」 という基本をしっかり身につけることが大切です。

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

生徒:「ローディング状態を入れるだけで、画面の印象が全然変わりますね。」

先生:「そうですね。ユーザーは処理の中身よりも、今何が起きているかを知りたいんです。」

生徒:finallyを使えば、失敗してもローディングが止まるのが安心です。」

先生:「そこが重要なポイントです。実務では、この書き忘れが原因の不具合もよくあります。」

生徒:「ボタンを無効化するのも、ユーザーのためなんですね。」

先生:「はい。操作できない理由が分かるだけで、使いやすさは大きく向上します。」

生徒:「これからは、非同期処理には必ずローディングをセットで考えます。」

先生:「その意識があれば、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とTypeScriptの環境構築をやさしく解説!Viteとtsconfigの設定も丁寧に紹介
No.3
Java&Spring記事人気No3
React
Reactのイベントハンドリングのアンチパターンまとめ!初心者でもわかる注意点
No.4
Java&Spring記事人気No4
React
Reactのカスタムフックの作り方を完全ガイド!再利用可能なロジックを切り出す仕組み
No.5
Java&Spring記事人気No5
React
ReactでFetch APIのローディング状態を管理する方法|初心者にもわかる解説
No.6
Java&Spring記事人気No6
React
create-react-appでReactプロジェクトを作成する手順を初心者向けに完全解説!
No.7
Java&Spring記事人気No7
React
ReactのuseStateとuseEffectでよくあるエラーと解決方法ガイド!初心者でもわかるReactフック
No.8
Java&Spring記事人気No8
React
Reactでファイルアップロードを実装する方法を解説!Fetch APIで画像やPDFを送る仕組みを初心者向けに紹介