コース一覧
Next.jsフルスタック:サーバー・データ取得・API
検索をサーバーで

Next.jsフルスタック:サーバー・データ取得・API

Server ComponentsとClient Components、use client、サーバーfetch、asyncコンポーネント、動的ルート、params、notFound、キャッシュ、Route Handler、GET・POST API、Server Actions、フォームを扱う全24レッスンのフルスタックコースです。fleamaの商品取得と出品機能をNext.js内へ実装します。

1
Server / Client Components
01. サーバーで動く部品10分
02. Server Components15分
03. use clientの宣言15分
04. どちらに置くか15分
05. 境界をまたぐ合成15分
06. 境界の設計15分
07. つくる - 部品の仕分け20分
08. 第4章クイズ15分
2
データ取得と動的ルート
01. サーバーでfetch15分
02. asyncコンポーネント15分
03. 動的ルート15分
04. paramsを受け取る15分
05. notFoundで404にする15分
06. キャッシュのきほん10分
07. 検索をサーバーで15分
08. つくる - サーバー取得化20分
09. 第5章クイズ15分
3
API Routesとフォーム
01. Route Handler15分
02. GET APIを作る15分
03. POST APIを作る15分
04. Server Actionsの触り15分
05. フォーム実装15分
06. つくる - 受け口の完成20分
07. 第6章クイズ15分

検索をサーバーで

検索をサーバーで絞る

絞り込みを URL に持たせる

React で作った検索は、入力した文字を useState に持っていました。動きはしますが、絞り込んだ結果を人に送れません。URL がずっと /items のままだからです。

Next.js では、絞り込みの条件を URL のクエリに置きます。/items?category=shoes を開けば誰でも同じ結果が見られますし、ブラウザの戻るボタンも効きます。検索エンジンもこの URL を1ページとして扱えます。

searchParams で受け取る

クエリはページの searchParams という props に入ってきます。params と同じく Promise なので await して開けます。

TypeScript (JSX)

type Props = { searchParams: Promise<{ category?: string }>; }; export default async function ItemsPage({ searchParams }: Props) { const { category } = await searchParams; const url = category ? `/api/items?category=${category}` : "/api/items"; const res = await fetch(url); const items = await res.json(); return <p>{items.length} 件</p>; }

型は省略できるものとして書く

クエリは付いていないこともあります。/items で開かれれば category は undefined です。だから型は category?: string のように省略できる形にします。

無いときにどうするかも決めておきます。上の例では、条件が無ければ絞り込まない URL を使っています。空文字を渡してしまうと、名前が空の商品を探しにいく形になり、結果が0件になります。

演習

一覧ページを searchParams で絞り込めるようにします。

ヒント

props の型は { searchParams: Promise<{ category?: string }> } です

URL は const url = category ? ... : ... のように先に組み立てると読みやすくなります

無いときの表示は {category ?? "すべて"} で書けます

app/items/page.tsx
layout.tsx
app/page.tsx
mock-api.json
プレビュー

できているか

  • くつを選ぶと2件に絞り込まれる
  • キッチンを選ぶと1件になる
  • すべてに戻すと5件に戻る
  • searchParams を await して使っている
エディタを読み込んでいます