検索条件を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 と同期させます。