ReactでFetch APIにタイムアウト処理を追加する方法を解説!初心者向けにやさしく解説
生徒
「ReactでFetch APIを使ってサーバーと通信したんですが、たまに応答が返ってこないんです…」
先生
「それはサーバーが重くて時間がかかっているのかもしれませんね。そんなときは“タイムアウト処理”を入れると安心です。」
生徒
「タイムアウト処理って何ですか?Reactでもできますか?」
先生
「もちろんReactでもFetch APIにタイムアウト処理を追加できますよ。今回はその方法をわかりやすく解説していきましょう!」
1. タイムアウト処理とは?
タイムアウト処理とは、「ある一定の時間が過ぎても結果が返ってこなかったら処理を中断する」という仕組みのことです。サーバーが遅かったり、通信が不安定だったりすると、ずっと画面が読み込み中になってしまうことがあります。
そこで、あらかじめ「5秒以内に返ってこなければ諦める」というように設定することで、画面のフリーズやユーザーのストレスを減らすことができます。
2. Fetch APIにはタイムアウト機能がない?
意外に思われるかもしれませんが、fetch()という関数には最初からタイムアウトの機能が組み込まれていません。そのため、ReactでFetch APIを使うときは、自分でタイムアウト処理を追加する必要があります。
そこで使うのが「AbortController(アボートコントローラー)」という機能です。
3. AbortControllerとは?
AbortControllerは、Fetch APIの通信を途中でキャンセル(中止)するための仕組みです。これを使うことで、「時間がかかりすぎた通信は中断する」というタイムアウト処理を作ることができます。
AbortControllerは以下のように使います。
const controller = new AbortController();
const signal = controller.signal;
fetch("URL", { signal })
.then(...)
.catch(...);
// 一定時間後に中止
setTimeout(() => controller.abort(), 5000);
このように、signalをfetchに渡し、時間が来たらabort()を呼ぶことで通信を中止できます。
4. ReactでFetchのタイムアウト処理を組み込む
それでは、Reactで実際にタイムアウト処理を組み込んだサンプルを見てみましょう。今回は、ボタンを押すとAPIにリクエストを送り、3秒以上応答がない場合はキャンセルされるようにします。
import React, { useState } from "react";
function App() {
const [message, setMessage] = useState("データ取得前");
const fetchDataWithTimeout = async () => {
const controller = new AbortController();
const timeoutId = setTimeout(() => {
controller.abort();
}, 3000); // 3秒でタイムアウト
try {
const response = await fetch("https://api.example.com/data", {
signal: controller.signal,
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error("サーバーエラー");
}
const data = await response.json();
setMessage(data.message);
} catch (error) {
if (error.name === "AbortError") {
setMessage("タイムアウトしました");
} else {
setMessage("通信エラーが発生しました");
}
}
};
return (
<div>
<h1>{message}</h1>
<button onClick={fetchDataWithTimeout}>データ取得</button>
</div>
);
}
export default App;
5. タイムアウト時間は調整できる
上記の例では「3秒」で設定しましたが、タイムアウトの時間は自由に調整できます。たとえば、サーバーが重くなりがちな場合は「5秒」や「10秒」にすることも可能です。
ただし、長すぎるとユーザーが待ちくたびれてしまうので、適切な時間を選ぶのがポイントです。
6. タイムアウト処理が便利な場面とは?
- 外部APIの応答が不安定なとき
- モバイル回線などで通信が遅い環境
- スピードを重視したいアプリ(チャット、検索など)
こうした場面では、タイムアウト処理を入れることで、ユーザー体験(UX)を向上させることができます。
7. タイムアウト時のエラーハンドリングも大切
タイムアウト処理を入れたら、次に大切なのは「失敗したときに何を表示するか」です。「通信に失敗しました」「もう一度お試しください」など、ユーザーに分かりやすいメッセージを表示することで、混乱を防げます。
また、必要に応じて再試行ボタンなどを用意すると、より親切な設計になります。
まとめ
ReactでFetch APIを使った通信処理にタイムアウトを組み込むことは、ユーザー体験を大きく向上させる重要なポイントです。通信が遅い環境や外部APIの応答が不安定な状況では、いつまでも画面に変化がなく、利用者が不安を抱いてしまうことがあります。そうした状況を避けるために、一定時間応答がなければ処理を中断し、ユーザーにわかりやすいメッセージを返す仕組みが「タイムアウト処理」です。とりわけReactのように動的なUIを扱うフレームワークでは、タイムアウトを適切に扱うことで画面の動きを自然に保ち、不要な待ち時間を減らすことができます。今回の記事で紹介したAbortControllerは、Fetch APIと相性が良く、通信を途中で中止できる便利な機能で、タイムアウトの実装には欠かせない存在です。 また、タイムアウト処理を実装する際には、適切な秒数を設定するだけでなく、失敗時のエラーハンドリングもとても大切です。ユーザーに誤解を与えないよう、「通信が遅れているのか」「エラーが発生したのか」「再試行すべきなのか」といった情報を明確に示すことが、わかりやすいUIを作るためのポイントになります。Reactでは状態管理が容易なため、メッセージの切り替えやボタンの操作なども柔軟に行えるため、タイムアウト処理とUIの変更を組み合わせて実装すれば、より快適なアプリケーションを作ることができます。 以下に、今回の内容をもとに作ったサンプルプログラムをまとめてあります。記事内のコードと同じようにclassやタグを用いながら、Reactでのタイムアウト処理をさらに理解しやすい形で示しています。
サンプルプログラム:応答が遅いAPIにタイムアウトを適用するコンポーネント
import React, { useState } from "react";
function TimeoutSample() {
const [status, setStatus] = useState("通信待機中…");
const callApi = async () => {
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 4000); // 4秒でタイムアウト
try {
const response = await fetch("https://slow.example.com/api", {
signal: controller.signal,
});
clearTimeout(timeout);
if (!response.ok) {
throw new Error("通信エラー");
}
const data = await response.json();
setStatus("結果:" + data.result);
} catch (error) {
if (error.name === "AbortError") {
setStatus("通信が遅いため中断しました");
} else {
setStatus("エラーが発生しました");
}
}
};
return (
<div className="card p-3 mb-3">
<h2 className="fw-bold fs-4">タイムアウト処理例</h2>
<p>{status}</p>
<button className="btn btn-primary mt-2" onClick={callApi}>
通信を開始する
</button>
</div>
);
}
export default TimeoutSample;
上記の例では、4秒以内に応答が返らない場合に通信を中断し、ユーザーに対して明確なメッセージを表示しています。このように、AbortControllerを使ったタイムアウト実装は、通信状態を安全に管理するための基礎であり、実務でもさまざまな場面で応用されています。特にチャットアプリや検索機能のように「スピード」が求められる機能では、適切なタイムアウト処理が非常に効果的です。 また、画面に応じて数秒の設定を変えることで、用途ごとに最適な動作を実現できます。通信が遅くなりやすいモバイル環境では少し長めに、ユーザーがすぐに結果を求める場面では短めに設定するなど、工夫次第でUIの品質を高めることができます。ReactとFetch APIは柔軟で扱いやすい組み合わせであるため、今回のタイムアウト処理の考え方をしっかり理解しておけば、より高度な通信制御やエラーハンドリングへ応用できるようになります。
生徒
「Fetch APIにタイムアウトをつけられるって知らなかったです!AbortControllerって便利なんですね。」
先生
「とても便利ですよ。タイムアウトを設定しておくと、通信が遅いときにも画面が止まらず安心です。」
生徒
「たしかに…ずっと読み込み中だと不安になりますもんね。表示するメッセージも大事なんですね!」
先生
「その通りです。エラーの伝え方ひとつで使いやすさは大きく変わります。Reactは状態管理がしやすいので、こうした工夫がしやすいんですよ。」
生徒
「AbortControllerを使う場面もイメージしやすくなりました!実際の開発でも使ってみたいです。」
先生
「ぜひ挑戦してみてください。通信をうまく制御できるようになると、Reactアプリの品質がぐっと上がりますよ。」