Summary
React開発でfetch APIに苦戦していた私が、axiosに切り替えた途端にコードが驚くほどスッキリした体験を赤裸々に語ります。特にエラーハンドリングや非同期処理の煩雑さから解放された実感は、同じ悩みを持つ開発者に刺さるはず。 Key Points:
- fetch APIでよくハマるポイント(リクエストキャンセルできない・エラーハンドリングが面倒など)をAxiosならスマートに解決できる実例を紹介
- Reactプロジェクトでaxiosを導入する具体的な手順と、インターセプターを使った効率的なAPI通信のコツ
- 「シンプルなGETならfetchで十分」という意見への反論と、大規模アプリでこそ活きるAxiosの真価
正直に言うと、Reactで`fetch` APIを使ってて、変なレスポンスの動きとか、手動でJSON解析しなきゃいけなかったり、エラー処理が意味不明だったり…そんな経験、結構多いんじゃないかな?僕だけじゃなくて、多分みんな一度は通る道だと思う。まだメンバーじゃない?[ここを読んでね!]それにしてもReact開発者なら絶対知っておくべきなんだよね。Axiosを使った方がいいって話もあるし。ただまあ、大体そんな感じで、fetchって意外と扱いにくい時あるよね…。
さて、ここでちょっとした辛口意見を。_👉 変な使い方してるなら`fetch`はやめて、代わりに`Axios`を使い始めたほうがいいよ!_ 今回はかなり深掘りするつもり。内容はこんな感じ:- 🔍 なぜか多くの開発者が`fetch`でつまずく理由- 🚀 Reactでの開発がグッと楽になる`Axios`の魅力- 💡 `fetch`から`Axios`への置き換え方法(実例付き)- 🧪 おまけ:Axiosのインターセプターとかエラーハンドリング、非同期処理のコツ- 📦 それでも「fetch」で十分な場合もあるって話(ほんとに!)
読み終わるころには、なんでAxiosが優れてるのかだけじゃなくて、どうやってスムーズに移行できるかもわかって、もっと読みやすく保守しやすいReactコードが書けるようになっているはず。
---
## 😩 `fetch`を使う時によくある残念な現実
まずは、多くのReact開発者が最初にトライするであろうデフォルト手段、つまり`fetch`について。動くっちゃ動くんだけど…まあ微妙というか。
読み終わるころには、なんでAxiosが優れてるのかだけじゃなくて、どうやってスムーズに移行できるかもわかって、もっと読みやすく保守しやすいReactコードが書けるようになっているはず。
---
## 😩 `fetch`を使う時によくある残念な現実
まずは、多くのReact開発者が最初にトライするであろうデフォルト手段、つまり`fetch`について。動くっちゃ動くんだけど…まあ微妙というか。
Extended Perspectives Comparison:
項目 | 説明 |
---|---|
POSTリクエストの基本 | axios.postを使用してフォームデータを送信する方法。 |
async/awaitの活用 | 非同期処理をシンプルに記述し、エラー処理も容易に行える。 |
Axiosインターセプターの利点 | 共通ヘッダーやエラーハンドリングを一元管理できるため、効率的なリクエストが可能。 |
AbortControllerによるメモリリーク防止 | コンポーネントがアンマウントされてもリクエストをキャンセルできる機能で安全性向上。 |
ベストプラクティスまとめ | Axiosインスタンス作成、タイムアウト設定、インターセプター利用、キャンセル処理などが推奨される。 |

でも、頭痛の種がないわけじゃない。たとえば典型的なfetchの呼び出しはこんな感じで。
まぁ、一見普通に見えるよね?でもこれがReactコンポーネント内だと…
ここからちょっとややこしくなるんだ。
- JSONを自分で解析しなきゃいけない(多分) 。
- HTTPのエラーも自分でチェックしないと、`.then`が普通に動いちゃう 。
- リクエストキャンセル機能は基本なし(コンポーネントアンマウント時とか危険かも)。
- タイムアウトサポートも最初からは無いような気がする。
- ヘッダーやボディ設定を何度も繰り返すことになりやすい 。
って感じで、まあ使いやすいとは言えないかもね。
fetch("https://api.example.com/data")
.then((response) => {
if (!response.ok) {
throw new Error("ネットワークの応答が正常じゃなかった");
}
return response.json();
})
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error("fetch操作に問題があったみたい:", error);
});
まぁ、一見普通に見えるよね?でもこれがReactコンポーネント内だと…
useEffect(() => {
fetch("https://api.example.com/data")
.then((response) => {
if (!response.ok) {
throw new Error("データ取得失敗"); // 多分こういうエラー処理は必要になるよね?
}
return response.json();
})
.then((data) => setData(data))
.catch((error) => setError(error.message));
}, []);
ここからちょっとややこしくなるんだ。
- JSONを自分で解析しなきゃいけない(多分) 。
- HTTPのエラーも自分でチェックしないと、`.then`が普通に動いちゃう 。
- リクエストキャンセル機能は基本なし(コンポーネントアンマウント時とか危険かも)。
- タイムアウトサポートも最初からは無いような気がする。
- ヘッダーやボディ設定を何度も繰り返すことになりやすい 。
って感じで、まあ使いやすいとは言えないかもね。
そしてこれはGETリクエストの場合だけの話です。POSTでネストされたヘッダーやエラー解析になると、もう目が回りそうですよね😵
🚀 さて、Axiosをご紹介しましょう。Reactでの新しい心強い味方です。AxiosはブラウザやNode.js向けの**PromiseベースのHTTPクライアント**で、Reactとの相性も抜群です。なぜ多くの開発者がAxiosを好むのでしょうか?その理由はこんなところにあります:自動的にJSONをパースしてくれるし、`if (!res.ok)`みたいな面倒なチェックが不要だったり、リクエストやレスポンスのインターセプターもサポートしていて、エラーハンドリングもシンプル。さらにリクエストキャンセル機能やタイムアウト設定も標準装備されているので、async/awaitとも相性バッチリなんです。
先ほどのfetch例をAxiosで書き直すとこんな感じになります:
これで完璧です。
🚀 さて、Axiosをご紹介しましょう。Reactでの新しい心強い味方です。AxiosはブラウザやNode.js向けの**PromiseベースのHTTPクライアント**で、Reactとの相性も抜群です。なぜ多くの開発者がAxiosを好むのでしょうか?その理由はこんなところにあります:自動的にJSONをパースしてくれるし、`if (!res.ok)`みたいな面倒なチェックが不要だったり、リクエストやレスポンスのインターセプターもサポートしていて、エラーハンドリングもシンプル。さらにリクエストキャンセル機能やタイムアウト設定も標準装備されているので、async/awaitとも相性バッチリなんです。
先ほどのfetch例をAxiosで書き直すとこんな感じになります:
import axios from "axios";
useEffect(() => {
axios.get("https://api.example.com/data")
.then((response) => setData(response.data))
.catch((error) => setError(error.message));
}, []);
これで完璧です。

## 🔁 Fetch と Axios:ざっくり比較してみた!
[]
👉 まあ、もし苦行が好きでなければ(😅)、Axios の方が賢い選択かも。
---
## 🔧 React に Axios を入れるのは簡単すぎる話
yarn 使うならこっち:
あとはインポートするだけっす:
---
## 💡 React でよくある Axios の使いどころをちょっと紹介しようかなと思うんだよね。
### ✅ 1. `useEffect` を使った基本的な GET リクエストって感じ?
こんな感じでAxiosはわりとシンプル&パワフルに使える気がするんだよね。まあFetchでもできるけど、煩雑さとか考えると、こっちのほうがいいかも? って話。
[]
👉 まあ、もし苦行が好きでなければ(😅)、Axios の方が賢い選択かも。
---
## 🔧 React に Axios を入れるのは簡単すぎる話
npm install axios
yarn 使うならこっち:
yarn add axios
あとはインポートするだけっす:
import axios from "axios";
---
## 💡 React でよくある Axios の使いどころをちょっと紹介しようかなと思うんだよね。
### ✅ 1. `useEffect` を使った基本的な GET リクエストって感じ?
import { useEffect, useState } from "react";
import axios from "axios";
function App() {
const [data, setData] = useState([]);
const [error, setError] = useState("");
useEffect(() => {
// URLはなんか有名なやつで、投稿データを取得するらしいよ。
axios.get("https://jsonplaceholder.typicode.com/posts")
.then((res) => setData(res.data))
.catch((err) => setError(err.message));
}, []);
return (
<div>
{error && <p>❌ エラー: {error}</p>}
{/* 投稿タイトルを数十件くらい表示している感じ */}
{data.map((post) => (
<div key={post.id}>{post.title}</div>
))}
</div>
);
}
こんな感じでAxiosはわりとシンプル&パワフルに使える気がするんだよね。まあFetchでもできるけど、煩雑さとか考えると、こっちのほうがいいかも? って話。
### 📝 2.POSTリクエスト(フォーム送信)
axios.post("https://api.example.com/posts", {
title: "新しい投稿",
body: "これは内容です。",
})
.then((res) => console.log(res.data))
.catch((err) => console.error(err));
### 🧼 3.Axiosを使った`async/await`の例
dart
const fetchData = async () => {
try {
const response = await axios.get("https://api.example.com/items");
setItems(response.data); // 多分データは数十件くらいかな?
} catch (error) {
setError(error.message); // エラー時はこんな感じで処理してる気がする…
}
};
こんな感じで、`.then()`や`.catch()`のネストなしで、コードがわりとスッキリ書けるって話だったと思う。
axios.post("https://api.example.com/posts", {
title: "新しい投稿",
body: "これは内容です。",
})
.then((res) => console.log(res.data))
.catch((err) => console.error(err));
### 🧼 3.Axiosを使った`async/await`の例
dart
const fetchData = async () => {
try {
const response = await axios.get("https://api.example.com/items");
setItems(response.data); // 多分データは数十件くらいかな?
} catch (error) {
setError(error.message); // エラー時はこんな感じで処理してる気がする…
}
};
こんな感じで、`.then()`や`.catch()`のネストなしで、コードがわりとスッキリ書けるって話だったと思う。

🔐 Axiosのインターセプターって、結構すごいんだよね。たとえば、認証トークンをほぼ全部のリクエストにくっつけたいとか、エラーを一括で処理したいみたいな場合とか。Axiosなら、そのへんまあまあ簡単にできる感じ。
こんな風に、リクエストが行く前にトークンをセットするコードがあったりして、localStorageから「auth_token」みたいなのを取ってきて、それがあればヘッダーのAuthorizationに「Bearer ○○」って入れちゃうわけ。全部のリクエストに付けられるから、大きめのアプリだとかなり便利かもね。
あと、レスポンスで返ってくるエラーもまとめて処理できたりして。例えば、「401」が返ってきたら、「セッション切れたからまたログインしてね」みたいな警告を出すとか。こういうグローバルな設定は、まぁ、大体どんなアプリでも役立つと思うよ。
なんか細かいところ忘れてる気もするけど、多分こんな感じで使うんじゃないかなー。ちょっと複雑だけど慣れると超強力!
こんな風に、リクエストが行く前にトークンをセットするコードがあったりして、localStorageから「auth_token」みたいなのを取ってきて、それがあればヘッダーのAuthorizationに「Bearer ○○」って入れちゃうわけ。全部のリクエストに付けられるから、大きめのアプリだとかなり便利かもね。
あと、レスポンスで返ってくるエラーもまとめて処理できたりして。例えば、「401」が返ってきたら、「セッション切れたからまたログインしてね」みたいな警告を出すとか。こういうグローバルな設定は、まぁ、大体どんなアプリでも役立つと思うよ。
なんか細かいところ忘れてる気もするけど、多分こんな感じで使うんじゃないかなー。ちょっと複雑だけど慣れると超強力!
「Reactのアンマウントされたコンポーネントで状態更新できません」みたいな警告、見たことあるならわかると思うけど、あれほんと厄介。Axiosだと、その辺ちょっと楽になるかも?例えばこんな感じで。
useEffectの中にAbortControllerを作って、それをAxiosのリクエストにsignalとして渡すんだよね。で、なんか数十件くらいデータ取ってきてsetStateする。でも途中でコンポーネントが消えたりしたら、そのcontroller.abort()呼ぶことでリクエストキャンセルできるってわけ。これやっとくと、「もう更新できないよ!」みたいな警告出なくなる。
ただしcatchのところでキャンセルかどうか判定して、そうじゃないエラーだけちゃんと処理するみたいな感じ。これ結構知られてるけど意外に使ってない人多い気もする。
ちなみにこの例ではjsonplaceholderから投稿データ(確か70件くらい?)取得してて、表示部分は省略してるけど割と安全に動くはず。まぁ完璧じゃないかもだけど、メモリリークとか無駄なstate更新はかなり防げると思う。
要はこういう小技入れるだけでReactアプリの安定性がグッと上がる感じ。ただ、細かいところは色々環境やバージョンによって違うこともあるから、一応自分でもテストしながらやったほうがいいかな~なんて思う。
まあとにかく、キャンセル機能使えば「変な警告出ちゃった…」みたいなの減るし、メモリリーク問題もちょっとは解決できそうだよ!
useEffectの中にAbortControllerを作って、それをAxiosのリクエストにsignalとして渡すんだよね。で、なんか数十件くらいデータ取ってきてsetStateする。でも途中でコンポーネントが消えたりしたら、そのcontroller.abort()呼ぶことでリクエストキャンセルできるってわけ。これやっとくと、「もう更新できないよ!」みたいな警告出なくなる。
ただしcatchのところでキャンセルかどうか判定して、そうじゃないエラーだけちゃんと処理するみたいな感じ。これ結構知られてるけど意外に使ってない人多い気もする。
ちなみにこの例ではjsonplaceholderから投稿データ(確か70件くらい?)取得してて、表示部分は省略してるけど割と安全に動くはず。まぁ完璧じゃないかもだけど、メモリリークとか無駄なstate更新はかなり防げると思う。
要はこういう小技入れるだけでReactアプリの安定性がグッと上がる感じ。ただ、細かいところは色々環境やバージョンによって違うこともあるから、一応自分でもテストしながらやったほうがいいかな~なんて思う。
まあとにかく、キャンセル機能使えば「変な警告出ちゃった…」みたいなの減るし、メモリリーク問題もちょっとは解決できそうだよ!

🎯 ReactでAxios使うときのベストプラクティスみたいなやつ、知ってる?ざっくり言うとね… ✅ Axiosのインスタンス作っとくと便利。ベースURLとかヘッダーまとめられるし。 ✅ あと、グローバルにタイムアウト設定しとかないと、リクエストがずーっと終わらないこともあるから注意。 ✅ トークン処理とか共通エラー対応はインターセプター使うと楽チンらしい。これ結構ありがたいかも。 ✅ それからReactのuseEffectでリクエストするときはキャンセルもちゃんとしておいたほうがいいんだって。メモリリーク防止になるって聞いたよ。 ✅ ちなみにAxiosはユーティリティ用のフォルダにまとめておくのが再利用しやすいみたい。
こんな感じでAxiosインスタンス作るのが普通っぽい:
で、それをコンポーネント内でこう使う感じ。
あんまり細かく覚えてないけど、多分こんな感じで効率よくAxios使えるんだと思うよ。
こんな感じでAxiosインスタンス作るのが普通っぽい:
// src/utils/axiosInstance.js
import axios from "axios";
const instance = axios.create({
baseURL: "https://api.example.com", // ここはまあ大体決まったAPIのURL
timeout: 5000, // タイムアウトは数秒くらいかな?完全じゃないけど
headers: {
"Content-Type": "application/json",
},
});
export default instance;
で、それをコンポーネント内でこう使う感じ。
import axiosInstance from "../utils/axiosInstance";
axiosInstance.get("/posts").then((res) => console.log(res.data));
あんまり細かく覚えてないけど、多分こんな感じで効率よくAxios使えるんだと思うよ。
🤔 でも、待って… `fetch` は本当に使う価値あるの?たぶん、そう!もしやってることが、めちゃくちゃシンプルなGETリクエストとか、小さなスクリプトとか、一度きりのツールだったら、それだけで十分かもね。依存関係を減らしたい超ミニマルなアプリにも意外と合うかも。
けど、本当のところReactの現場で認証とかローディング状態、エラーハンドリングなんかが絡むと……まあ、規模が大きくなるなら間違いなくAxios推しだよね。まぁ、Axiosの方が色々便利っぽいし。
あーそうそう、参考資料はAxiosの公式ドキュメントとかReactのデータフェッチングに関するページ、それからGitHubにあるAwesome Axiosリポジトリなんかも見ておくといいかも。そんな感じかな?
けど、本当のところReactの現場で認証とかローディング状態、エラーハンドリングなんかが絡むと……まあ、規模が大きくなるなら間違いなくAxios推しだよね。まぁ、Axiosの方が色々便利っぽいし。
あーそうそう、参考資料はAxiosの公式ドキュメントとかReactのデータフェッチングに関するページ、それからGitHubにあるAwesome Axiosリポジトリなんかも見ておくといいかも。そんな感じかな?
Reference Articles
Advent Calendar 2017 · GitHub
Advent Calendar 2017. GitHub Gist: instantly share code, notes, and snippets.
Source: Gist
Related Discussions