← inaro.devAI駆動開発 学習ツール
応用

URLで状態を持つ

なぜ学ぶか: 検索キーワードやページ番号をuseStateだけで持つと、「リロードで消える・URLを人に送れない」という弱点があります。答えは「状態をURLに置く」。例で見てください。

まずはこの例を見てみましょう

// /search?q=react のような URL の「?q=…」を読む
export default async function SearchPage({
  searchParams,
}: {
  searchParams: Promise<{ q?: string }>;
}) {
  const { q = "" } = await searchParams;

  return <p>「{q}」の検索結果を表示</p>;
}
// この URL を人に送れば、相手にも同じ検索結果が見える

検索条件がURLに入っているので、リロードしても消えず、リンクとして共有できます。

URL=共有できる状態置き場

?q=reactのような部分は「アプリの状態」の置き場になります。リロードしても消えず、リンクで共有でき、戻るボタンも効きます。

searchParamsで受け取る

例のように、ページの引数searchParamsから読みます。動的ルートのparamsの兄弟です。

stateとURLの使い分け

共有・保存したい状態(検索条件・タブ)→ URL。一時的な状態(モーダルの開閉・入力途中)→ useState。

コード例

// app/search/page.tsx — URL の ?q=... を読む検索ページ
export default async function SearchPage({
  searchParams,
}: {
  searchParams: Promise<{ q?: string }>;
}) {
  const { q = "" } = await searchParams;
  const items = ["React 入門", "Next.js 実践", "TypeScript 基礎"];
  const results = q ? items.filter((i) => i.includes(q)) : items;

  return (
    <div>
      <form>
        <input name="q" defaultValue={q} placeholder="検索" />
        <button>検索</button>
      </form>
      <ul>{results.map((r) => <li key={r}>{r}</li>)}</ul>
    </div>
  );
}

期待される出力

/search?q=React にアクセスすると:
「React 入門」だけが表示される

この検索結果はURLごと共有できます(相手にも同じ結果が見える)。useStateだけの検索では実現できない価値です。

ステップ 1 / 2

※ カリキュラムの内容はAIが生成しており、誤りが含まれる場合があります。正確な情報は公式ドキュメント等でご確認ください。