検索条件をURLに

検索した画面を人に見せられない

第1章で作った検索欄は、打った言葉を useState に持っていました。動きはしますが、絞り込んだ結果を人に送れません。URL がずっと /items のままだからです。読み込み直せば条件も消えます。

商品を探す条件は、その人がいま見ている画面そのものです。画面を表すものは URL に置くと考えると、置き場所は useState ではなく URL になります。

クエリ文字列

URL の ? から後ろをクエリ文字列と呼びます。

/items?q=革 /items?q=革&category=shoes

& でいくつでも並べられます。この形なら、そのまま貼って渡せば相手も同じ絞り込みを見られます。ブラウザの履歴にも残るので、戻るボタンで1つ前の条件に戻れます。

useSearchParams

読み書きは useSearchParams でやります。useState によく似た形です。

import { useSearchParams } from "react-router"; const [searchParams, setSearchParams] = useSearchParams(); const keyword = searchParams.get("q") ?? "";

get は無いときに null を返すので、?? "" で空文字にしておきます。これで keyword は必ず string になり、そのまま value に渡せます。

書き込みは setSearchParams です。

<input className="search" value={keyword} onChange={(e) => setSearchParams({ q: e.target.value })} />

打つたびに URL が書き換わり、その変化で部品が描き直されます。state は1つも持っていません。URL が唯一の置き場所になっている、というのがこの回の要点です。プレビューでは、打つたびに画面の上の帯が変わるのが見えます。

何を URL に置くか

何でも URL に入れればよいわけではありません。目安は「人に送ったときに同じ画面が見えてほしいか」です。検索語や並び順や表示中のページ番号は入れます。入力途中のフォームや、開いているかどうかだけのメニューは入れません。

演習

商品一覧の検索欄を、URL と同期させます。

ヒント

App.tsx
App.tsx
プレビュー

できているか

  • 一覧に検索欄と3件の商品が出ている
  • 革 と打つと革靴だけに絞り込まれる