ReactのFetch APIでエラー処理を理解しよう!初心者でも安心のやさしい解説
生徒
「Reactでサーバーにアクセスしたときに、エラーが起きたらどうなりますか?」
先生
「その場合は、Fetch APIを使ったエラーハンドリング(エラー処理)が重要になります。」
生徒
「エラーハンドリングって難しそうですね…」
先生
「大丈夫です!ReactでFetch APIを使って、エラーが起きたときに正しく対処する方法をわかりやすく解説します。」
1. Reactでサーバー通信するとは?
React(リアクト)は、ユーザーの操作に応じて画面を動的に更新できる人気のJavaScriptライブラリです。サーバーとやりとりすることで、データを取得したり送信したりできます。この通信のときに使われるのが「Fetch API(フェッチエーピーアイ)」です。
Fetch APIは、Webブラウザにもともと備わっている機能で、「fetch()」という命令を使ってサーバーと通信を行います。
2. なぜエラーハンドリングが必要なの?
インターネットを使っていると、通信が失敗することがあります。たとえば「サーバーが停止している」「URLが間違っている」「ネットが不安定」などの理由です。
もしエラーが起きたときに何も対処しないと、Reactアプリは止まったり、ユーザーに誤った情報を見せてしまいます。だからこそ、「エラーハンドリング=エラーが起きたときの処理」が大切なんです。
3. Fetch APIでエラーハンドリングする基本構文
まずは、ReactでFetch APIを使う基本の書き方と、エラーハンドリングの構文を見てみましょう。
import React, { useEffect, useState } from "react";
function App() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
fetch("https://api.example.com/data")
.then((response) => {
if (!response.ok) {
throw new Error("サーバーエラー: " + response.status);
}
return response.json();
})
.then((json) => {
setData(json);
})
.catch((err) => {
setError(err.message);
});
}, []);
return (
{error && <p style={{ color: "red" }}>エラーが発生しました: {error}</p>}
{data ? <pre>{JSON.stringify(data, null, 2)}</pre> : <p>読み込み中...</p>}
);
}
export default App;
4. .thenの中でもエラーは検知されない?
Fetch APIは通信に成功しただけでは「エラー」と判断しません。たとえば、サーバーから「404 Not Found」が返ってきても、それは通信成功と見なされてしまいます。
そこで「response.ok」を使って、サーバーが成功(200番台)を返しているか確認します。失敗していれば、手動で「throw new Error()」を使ってエラーを投げてあげます。
5. ネットワークエラーは.catchでキャッチ
ネットが切れていたり、サーバーに接続できないようなエラーは「catch」でまとめて処理できます。
このように「.thenでサーバーのステータスチェック」「.catchで通信失敗の処理」を行うのが基本的なエラーハンドリングの考え方です。
6. エラー内容をユーザーに丁寧に伝える
Reactのエラーハンドリングでは、ただconsole.logで出力するだけでなく、「ユーザーの目に見える形」で知らせてあげることも重要です。
たとえば、データ取得に失敗したら「現在、情報を取得できません」や「通信エラーが発生しました」などの文言を表示するようにしましょう。
7. エラーハンドリングの例をもう1つ
次はボタンをクリックしてデータ取得し、エラーがあったときにユーザーにメッセージを表示する例です。
import React, { useState } from "react";
function App() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const handleFetch = () => {
setError(null);
fetch("https://invalid-url.example.com/data")
.then((res) => {
if (!res.ok) {
throw new Error("ステータスコード: " + res.status);
}
return res.json();
})
.then((json) => {
setData(json);
})
.catch((err) => {
setError("通信に失敗しました: " + err.message);
});
};
return (
{error && <p style={{ color: "red" }}>{error}</p>}
{data && <pre>{JSON.stringify(data, null, 2)}</pre>}
);
}
export default App;
8. よくある間違いと注意点
ReactでFetch APIを使うときによくある間違いに、「エラーが出ても何も表示されない」「画面が真っ白になる」という問題があります。
これは「catchを書いていない」「エラーメッセージを画面に出していない」「response.okを確認していない」といった原因が考えられます。
初心者の方は、まずは「fetch → then → catch」という基本の流れと、「エラーの表示場所」をしっかり押さえておきましょう。
9. 非同期処理(async/await)でもエラーハンドリングできる
実は、.thenや.catchを使わずに、async/await構文で書いても同じことができます。こちらの方が見やすいと感じる人も多いです。
import React, { useState } from "react";
function App() {
const [result, setResult] = useState(null);
const [error, setError] = useState(null);
const fetchData = async () => {
setError(null);
try {
const res = await fetch("https://api.example.com/data");
if (!res.ok) {
throw new Error("ステータスコード: " + res.status);
}
const json = await res.json();
setResult(json);
} catch (err) {
setError("エラー発生: " + err.message);
}
};
return (
<div>
<button onClick={fetchData}>データ取得</button>
{error && <p style={{ color: "red" }}>{error}</p>}
{result && <pre>{JSON.stringify(result, null, 2)}</pre>}
</div>
);
}
export default App;
まとめ
今回の記事では、ReactでFetch APIを使ったサーバー通信と、発生する可能性のあるエラーへの対処方法を詳しく解説しました。Fetch APIを使用すると、Webブラウザ内でサーバーと通信してデータを取得したり送信したりできますが、通信失敗やサーバーエラーが発生すると、画面が止まったり誤った情報が表示されたりする可能性があります。Reactでは、このようなケースに備えてエラーハンドリングが重要です。thenやcatch、あるいはasync/awaitを使うことで、通信エラーやサーバーエラーを正しく検知してユーザーに情報を伝えることができます。
まず、Fetch APIでは通信自体が成功したかどうかだけでなく、サーバーから返されるステータスコードも確認する必要があります。ステータスコードが200番台でなければ、throw new Error()を使って意図的にエラーを発生させ、catchでまとめて処理します。こうすることで、404や500などのサーバーエラーも見逃さずに処理可能です。また、Stateを使ってエラー内容や取得データを管理することで、画面に動的に反映させることができます。
ユーザーへの表示も重要で、単にconsoleに出力するだけでなく、赤文字や警告メッセージなどで丁寧に知らせることでUX(ユーザー体験)を損なわずに済みます。さらに、Fetch APIは非同期処理であるため、複数回の更新や連続クリックにも注意し、Stateの管理を適切に行うことが必要です。
import React, { useState } from "react";
function App() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const fetchData = async () => {
setError(null);
try {
const res = await fetch("https://invalid-url.example.com/data");
if (!res.ok) {
throw new Error("ステータスコード: " + res.status);
}
const json = await res.json();
setData(json);
} catch (err) {
setError("通信に失敗しました: " + err.message);
}
};
return (
{error && <p style={{ color: "red" }}>{error}</p>}
{data && <pre>{JSON.stringify(data, null, 2)}</pre>}
);
}
export default App;
生徒
「Fetch APIを使うときは、通信が成功したかだけでなく、ステータスコードもチェックする必要があるんですね。」
先生
「その通りです。200番台以外のレスポンスは、たとえ通信自体は成功してもエラーとして扱う必要があります。」
生徒
「catchでまとめて処理すると、ネットワークエラーや接続失敗も検知できるんですね。」
先生
「そうです。そしてStateを使ってエラー内容や取得データを管理することで、画面に動的に反映できるのもReactの強みです。」
生徒
「async/awaitを使うと、.thenや.catchよりもコードが読みやすくなるんですね。」
先生
「そうです。非同期処理の流れを直感的に書けるので、初心者でも理解しやすくなります。これでエラーハンドリングを正しく組み込めるようになりましたね。」