ReactのAPI GET処理:fetchJsonでJSON取得とエラーを共通化する
fetchでJSONを取得する独自関数を作り、HTTPエラー、JSON解析失敗、AbortSignal、取得データの検証を整理します。
fetchでJSONを取得する独自関数を作り、HTTPエラー、JSON解析失敗、AbortSignal、取得データの検証を整理します。
fetchJsonの役割と前提
通信処理をReactから分離する
fetchJson はURLからJSONを取得する自作の非同期関数です。Reactの組み込みAPIではありません。内部でHooksを使わないため、コンポーネント以外からも呼べます。読み込み表示などのstateは呼び出し側が担当します。
fetch はHTTP 404・500でも通常はResponseを返します。成功判定には response.ok が必要です。ネットワークの失敗とHTTPエラー、JSON解析の失敗は異なる段階で発生します。MDNのFetch解説を参考に、扱いを分けます。
src/api/fetchJson.tsの実装
引数と戻り値
url は取得先、任意の signal は中止通知です。戻り値は Promise<unknown> にし、APIの内容を未検証のまま既知の型だと扱わないようにします。
export async function fetchJson(
url: string,
signal?: AbortSignal,
): Promise<unknown> {
const response = await fetch(url, {
method: 'GET',
headers: { Accept: 'application/json' },
signal,
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json();
}JSON以外のHTMLエラーページが200で返る場合も、解析時に失敗します。204の空レスポンスを返すAPIもこの関数の対象外です。JSONを返すエンドポイントに使用し、空レスポンスやファイル取得は別の契約として実装します。
実行できる最小例
public/api/message.jsonを用意する
ViteなどのReact開発環境では public のファイルがルートから配信されます。外部APIのアカウントなしで、GETの動作を練習できます。
{ "message": "ReactからJSONを読み込みました" }src/App.tsxで表示する
import { useState } from 'react';
import { fetchJson } from './api/fetchJson';
export default function App() {
const [message, setMessage] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
async function handleLoad() {
setLoading(true);
setError('');
setMessage('');
try {
const data = await fetchJson('/api/message.json');
if (typeof data !== 'object' || data === null ||
!('message' in data) || typeof data.message !== 'string') {
throw new Error('messageの形式が不正です');
}
setMessage(data.message);
} catch (cause) {
setError(cause instanceof Error ? cause.message : '取得に失敗しました');
} finally {
setLoading(false);
}
}
return <main>
<h1>API読み込み</h1>
<button type="button" onClick={handleLoad} disabled={loading}>
{loading ? '読み込み中' : '取得する'}
</button>
{error && <p role="alert">{error}</p>}
<p aria-live="polite">{message}</p>
</main>;
}ファイル名を変更して失敗すること、message を数値へ変えて形式エラーになることを確認します。開発サーバーによっては不存在URLへHTMLを200で返すため、404の確認にはネットワークパネルで応答も確認してください。
実際のAPIへ切り替えるとき
CORS・認証・中止を区別する
別オリジンのAPIはサーバー側のCORS許可が必要です。mode: 'no-cors' を付けても読めるJSONにはなりません。ブラウザーへ機密APIキーを置かず、必要なら認証と権限確認を行うサーバーを経由します。
AbortController の signal を渡せば通信を中止できます。画面の切り替えやURL変更時の競合処理はuseApiDataの記事で実装します。このボタンの例は1回の操作の流れを示すもので、キャッシュや自動再試行を提供しません。
Googleの優先するニュース提供元にSEの部屋を追加
Googleで、いつも読みたい情報源を選べます。登録可否はGoogleの画面で確認できます。
候補にSEの部屋が表示されない場合は、まだ追加できません。