Next.js 15を基準にしています。更新でAPIが変わる場合があるため、公式ドキュメントも確認してください。
今回は、実際のサービスでよく使う
並列
、
順次
、
条件付き
という三つの取得パターンを見ます。
Client Componentsからデータを取得する方法も確認します。
複数のデータを同時に要求するなら、
並列fetch
のほうが効率的です。
JavaScriptの
Promise.all()を使います。
export default async function Page() {
const [postsRes, usersRes] = await Promise.all([
fetch('https://jsonplaceholder.typicode.com/posts'),
fetch('https://jsonplaceholder.typicode.com/users'),
]);
const posts = await postsRes.json();
const users = await usersRes.json();
return (
<>
<h2>Posts</h2>
<ul>
{posts.map((post: any) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
<h2>Users</h2>
<ul>
{users.map((user: any) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</>
);
}
二つの要求を
同時に実行
するため、順番に処理するより早く結果を得られます。
ある要求の結果が、次の要求のパラメーターに必要なら、
順次
送信する必要があります。
export default async function Page() {
const userRes = await fetch('https://jsonplaceholder.typicode.com/users/1');
const user = await userRes.json();
const postsRes = await fetch(
`https://jsonplaceholder.typicode.com/posts?userId=${user.id}`
);
const posts = await postsRes.json();
return (
<>
<h2>{user.name}의 게시글</h2>
<ul>
{posts.map((post: any) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</>
);
}
ユーザーIDを調べてから、そのIDに基づくデータを要求する場面に便利です。
条件に応じて
要求するかどうかを決めることもあります。
たとえば、特定のパラメーターがある場合だけ取得します。
export default async function Page({ searchParams }: { searchParams: { userId?: string } }) {
let posts = [];
if (searchParams.userId) {
const res = await fetch(
`https://jsonplaceholder.typicode.com/posts?userId=${searchParams.userId}`
);
posts = await res.json();
}
return (
<>
<h2>게시글 목록</h2>
{posts.length > 0 ? (
<ul>
{posts.map((post: any) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
) : (
<p>게시글이 없습니다.</p>
)}
</>
);
}
このようにsearchParamsに応じた取得ができます。
Client Componentsでのデータ取得 🔗
Server Componentsでは扱えず、クライアントから取得しなければならない場合もあります。
Reactの
useEffectや、SWRのようなフックライブラリを使えます。
'use client';
import { useEffect, useState } from 'react';
export default function Page() {
const [posts, setPosts] = useState<any[]>([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then((res) => res.json())
.then(setPosts);
}, []);
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
useEffectはマウント後に動くため、短い間ユーザーへ読み込み中の状態を表示する必要があります。
SWRは、Reactのデータ取得を便利にするフックです。
キャッシュ、再取得、エラー処理などを標準で提供します。
'use client';
import useSWR from 'swr';
const fetcher = (url: string) => fetch(url).then((res) => res.json());
export default function Page() {
const { data, error, isLoading } = useSWR(
'https://jsonplaceholder.typicode.com/posts',
fetcher
);
if (isLoading) return <p>로딩 중입니다...</p>;
if (error) return <p>데이터를 불러오는 데 실패했습니다.</p>;
return (
<ul>
{data.map((post: any) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
内部で効率的なキャッシュと同期を行い、ユーザー体験を改善できます。
実用的な三つの
fetchパターン
と、クライアント側の取得方法を学びました。
とくにSWRはClient Componentsで便利なので、ぜひ習得してください。
次回は
fetchのカスタマイズとキャッシュ無効化、Route Handlerによる通信を紹介します。
- 並列fetchと順次fetchは、それぞれどのような場面で使うとよいでしょうか。
- クライアントでのデータ取得では、SEOについて何に注意すべきでしょうか。