第83章:練習:詳細ページでIDを使って取得する🔎✨
今日は「一覧 → クリック → 詳細ページでIDつき取得」を完成させるよ〜!🎉
URLが /posts/1 みたいになるやつです🧩
(この章では、例として JSONPlaceholder の /posts/{id} を使います📮)
ゴール🎯
/postsに一覧がある前提で、各タイトルをクリックすると…/posts/1みたいな 詳細ページへ移動🧭- 詳細ページで URLの
idを使ってfetchして表示📥✨
図解:クリックして詳細が出るまで🗺️
params が Promise になってるのがポイントだよ〜!🧠✨ (Next.js)
1) フォルダを作る📁✨(動的ルート)
次の構成になるように作ってね👇
2) 詳細ページを作る🧾🔎(app/posts/[id]/page.tsx)
✅ Next.js 15以降は
paramsが Promise なので、awaitで取り出すよ! (Next.js) ✅PagePropsは、型生成(dev/build/typegen)後にグローバルで使えるよ! (Next.js)
import Link from "next/link";
import { notFound } from "next/navigation";
type Post = {
userId: number;
id: number;
title: string;
body: string;
};
async function getPost(id: number): Promise<Post | null> {
const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`);
if (res.status === 404) return null;
if (!res.ok) throw new Error("Failed to fetch post");
return res.json();
}
export default async function Page(props: PageProps<"/posts/[id]">) {
const { id } = await props.params;
const idNum = Number(id);
if (!Number.isInteger(idNum) || idNum <= 0) notFound();
const post = await getPost(idNum);
if (!post) notFound();
return (
<main style={{ padding: 24, maxWidth: 720, margin: "0 auto" }}>
<p>
<Link href="/posts">← 一覧へ戻る</Link>
</p>
<h1 style={{ marginTop: 16 }}>{post.title}</h1>
<p style={{ whiteSpace: "pre-wrap", lineHeight: 1.8 }}>{post.body}</p>
<hr style={{ margin: "24px 0" }} />
<small>
post id: {post.id} / user id: {post.userId}
</small>
</main>
);
}
🌟もし PageProps がまだ使えなかったら(すぐ直る版)
npm run dev を一度動かすと型生成されて直ることが多いよ〜🛠️✨ (Next.js)
それでも今すぐ進みたい時は、いったんこの書き方でもOK👇
export default async function Page({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
// あとは同じ!
}
3) 一覧から詳細へリンクする🔗✨(一覧ページ側)
/posts の一覧で、タイトルを Link にするだけ〜😊
(例:app/posts/page.tsx のリスト部分)
import Link from "next/link";
// ...
<li key={post.id}>
<Link href={`/posts/${post.id}`}>{post.title}</Link>
</li>
// ...
動作チェック✅🎮
-
npm run devで起動💨 -
ブラウザで
http://localhost:3000/posts(一覧)- そこからクリック →
/posts/1(詳細)
-
直打ちでもOK:
/posts/10とか 🔢✨
よくあるつまずき(ここだけ見て!)🧯
params.idが取れない:paramsは Promise だからawaitが必要だよ〜! (Next.js)- データ取得の基本:Server Component で
fetchしてawaitすればOK🍵 (Next.js)
おまけミニチャレンジ🎁✨
- 詳細ページに「次へ →」「← 前へ」ボタンを付けて、
idNum + 1に移動してみよ〜🚶♀️➡️🚶♀️ fetch(..., { cache: "no-store" })を付けて挙動の違いも見てみてね👀(更新系のAPIで差が出やすいよ) (Next.js)