ReactでFetch APIをカスタムフックで使いこなす!初心者でもわかるカスタムフック入門
生徒
「先生、Reactでデータを取得するFetch APIって何ですか?」
先生
「Fetch APIとは、インターネット上のサーバーから情報を取ってくるための仕組みです。例えば、天気の情報やニュース記事を読み込むときに使われます。」
生徒
「なるほど!でも毎回同じようなコードを書くのが面倒なんです…」
先生
「そんなときは、カスタムフックという仕組みで共通処理をまとめると便利ですよ!今回は、Fetch APIをカスタムフックでラップする方法を一緒に学んでいきましょう。」
1. Reactでデータを取得するには?
Reactでは、外部のサーバーやAPI(アプリケーション・プログラミング・インターフェース)から情報を取得するために、Fetch APIという機能がよく使われます。
Fetch APIは「フェッチ・エーピーアイ」と読みます。簡単に言うと、「お願い!このURLの情報を取ってきて!」という指示を出す機能です。
例えば、ニュース一覧やユーザー情報などをReactアプリに表示するために、サーバーからその情報を取得(リクエスト)します。そして、サーバーから返ってきた情報(レスポンス)を使って、画面に表示します。
2. カスタムフックとは?Reactで再利用できる便利な機能
Reactの「フック(Hook)」とは、関数コンポーネントで状態管理や副作用処理を行うための仕組みです。
そして「カスタムフック」とは、自分で作るオリジナルのフックのことです。
毎回同じようなデータ取得処理を書くのは面倒なので、それを1つの関数にまとめて使い回せるようにするのがカスタムフックの目的です。
名前は必ずuseで始める必要があります(例:useFetch)。Reactが「これはフックなんだ」と認識できるようにするためです。
3. useFetchカスタムフックのサンプルコード
それでは、実際にFetch APIをカスタムフックとしてまとめたコードを見てみましょう。
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState(null); // サーバーから取得したデータ
const [loading, setLoading] = useState(true); // 読み込み中フラグ
const [error, setError] = useState(null); // エラー情報
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url); // Fetch APIでデータ取得
if (!response.ok) {
throw new Error("サーバーエラーが発生しました");
}
const json = await response.json(); // JSONに変換
setData(json); // データ保存
setError(null); // エラーリセット
} catch (err) {
setError(err.message); // エラーメッセージ
setData(null); // データリセット
} finally {
setLoading(false); // ロード完了
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
export default useFetch;
4. カスタムフックを使ってデータを表示するコンポーネント
作ったuseFetchフックを、実際のReactコンポーネントで使ってみましょう。
import React from "react";
import useFetch from "./useFetch";
function UserList() {
const { data, loading, error } = useFetch("https://jsonplaceholder.typicode.com/users");
if (loading) return <p>読み込み中です...</p>;
if (error) return <p>エラー: {error}</p>;
return (
<ul>
{data.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
export default UserList;
5. なぜカスタムフックでラップするの?初心者にも嬉しい3つの理由
データ取得処理をカスタムフックでラップすることで、React初心者にもわかりやすく、効率的に開発が進められます。その理由は以下の3つです。
- 1. コードの重複を減らせる:同じような処理を何度も書かずに済む
- 2. 見通しが良くなる:コンポーネント本体がスッキリして読みやすくなる
- 3. 保守が簡単になる:修正が必要なときも1箇所を直すだけでOK
6. 初心者向けのよくある疑問Q&A
Q. Fetch APIは何に使うの?
A. サーバーから天気、ニュース、ユーザー情報などを取得するのに使います。
Q. カスタムフックって難しい?
A. 難しく聞こえますが、実態はただの関数です。ルールとしてuseから始めることと、Reactのフックを使えるようにするだけです。
Q. JSONって何ですか?
A. JSON(ジェイソン)は、データの形式の一つで、「名前と値」のペアで情報をやり取りできる仕組みです。
まとめ
今回の記事では、Reactにおけるデータ取得の要となるFetch APIと、それを劇的に扱いやすくするカスタムフック(Custom Hook)の作り方・活用方法について詳しく解説してきました。React開発において、外部APIからデータを取得し、画面に反映させるという工程は避けて通れない非常に重要なスキルです。
初心者の方が最初につまずきやすいポイントは、useEffectやuseStateを組み合わせて「非同期処理」を管理する部分です。しかし、今回学んだようにuseFetchというオリジナルの道具を自作してしまえば、それ以降のコードは驚くほどシンプルに記述できるようになります。プログラミングにおいて、「共通化できる部分は切り出す」という考え方は、保守性の高い、つまり「後で修正しやすい」コードを書くための基本中の基本です。
カスタムフック運用のコツと応用
実際にプロジェクトを進めていくと、単純にデータを取るだけでなく、データの更新(POST)や、通信中のスケルトンスクリーン表示など、さらに高度な要件が出てきます。今回作成したuseFetchをベースに、さらに「再試行機能」や「キャッシュ機能」を追加することで、より堅牢なアプリケーションへと進化させることが可能です。
また、TypeScript(TSX)を使用しているプロジェクトであれば、取得するデータの「型」を定義することで、より安全にコーディングができるようになります。以下に、少し応用編として、TypeScriptで型安全にFetchを行う例を紹介します。
import { useState, useEffect } from "react";
// 取得データの型定義(例:ユーザー情報)
interface User {
id: number;
name: string;
email: string;
}
function useFetchUsers(url: string) {
const [data, setData] = useState<User[] | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
if (!response.ok) throw new Error("データの取得に失敗しました");
const json = await response.json();
setData(json);
} catch (err: any) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
export default useFetchUsers;
このように型を定義することで、「このAPIからはどんなデータが返ってくるのか」をエディタが教えてくれるようになり、開発効率がさらに向上します。Reactの標準機能だけでは足りない部分を自分なりに拡張できるのが、カスタムフックの醍醐味ですね。
これからのステップ
カスタムフックの仕組みを理解できたら、次はReact Query (TanStack Query)やSWRといった、データ取得に特化した外部ライブラリのドキュメントを読んでみるのも良いでしょう。これらは今回自作したカスタムフックをより強力にしたようなライブラリです。基礎がわかっていれば、これらツールの恩恵もより深く理解できるようになるはずです。
まずは、手元の小さなプロジェクトで自分なりのuseFetchを動かしてみることから始めてみてください。実際に動くものを作ることが、上達への一番の近道です。
生徒
「先生、まとめまで読んでカスタムフックのすごさがよく分かりました!自分で作った関数なのに、まるでReactの標準機能みたいに使えるのが不思議ですね。」
先生
「その感覚、すごく大事だよ!実はカスタムフックを使うことで、コンポーネントは『どうやってデータを取るか』を知らなくて済むようになるんだ。コンポーネントは『届いたデータをどう表示するか』だけに集中できる。これを『関心の分離』って言うんだよ。」
生徒
「関心の分離……。難しそうですが、確かにUserListコンポーネントがすごくスッキリしました!以前はuseEffectがコードの真ん中にドーンとあって、何をしているのか読み解くのに時間がかかっていました。」
先生
「そうだね。特に複数の場所で同じAPIを叩くとき、カスタムフック化していないと、バグを直すときに全ての場所を修正して回らないといけなくなる。カスタムフックなら、useFetch.jsを1箇所直せば済むから、ミスも減るんだ。」
生徒
「なるほど。あと、TypeScriptの例もありがとうございます!型があると安心感が違いますね。次は自分で引数にオプション(methodやheaders)を渡せるように改良してみようと思います!」
先生
「素晴らしい意気込みだね。POSTリクエストなんかもカスタムフックに組み込めると、フォーム送信の処理もすごく楽になるよ。一歩ずつ、自分だけの便利なツールボックスを増やしていこう!」