Menu

useSearchParams

useSearchParamsは、現在のURLのクエリ文字列を読み取ることができるクライアントコンポーネントのフックです。

useSearchParamsは、URLSearchParamsインターフェースの読み取り専用バージョンを返します。

app/dashboard/search-bar.tsx
TypeScript
'use client'
 
import { useSearchParams } from 'next/navigation'
 
export default function SearchBar() {
  const searchParams = useSearchParams()
 
  const search = searchParams.get('search')
 
  // URL -> `/dashboard?search=my-project`
  // `search` -> 'my-project'
  return <>Search: {search}</>
}

パラメータ

const searchParams = useSearchParams()

useSearchParamsはパラメータを取りません。

戻り値

useSearchParamsは、URLのクエリ文字列を読み取るためのユーティリティメソッドを含むURLSearchParamsインターフェースの読み取り専用バージョンを返します:

  • URLSearchParams.get():検索パラメータに関連付けられた最初の値を返します。例:

    URLsearchParams.get("a")
    /dashboard?a=1'1'
    /dashboard?a=''
    /dashboard?b=3null
    /dashboard?a=1&a=2'1' - すべての値を取得するにはgetAll()を使用
  • URLSearchParams.has():指定されたパラメータが存在するかどうかを示すブール値を返します。例:

    URLsearchParams.has("a")
    /dashboard?a=1true
    /dashboard?b=3false
  • URLSearchParamsの他の読み取り専用メソッドについて詳しく学ぶ。getAll()keys()values()entries()forEach()toString()

補足

  • useSearchParamsクライアントコンポーネントのフックであり、部分的レンダリング中の古い値を防ぐため、サーバーコンポーネントではサポートされていません。
  • アプリケーションに/pagesディレクトリが含まれている場合、useSearchParamsReadonlyURLSearchParams | nullを返します。null値は、getServerSidePropsを使用しないページのプリレンダリング中にはSearch Paramsが不明であるため、移行時の互換性のためのものです。

動作

静的レンダリング

ルートが静的にレンダリングされる場合、useSearchParamsを呼び出すと、最も近いSuspense境界までのクライアントコンポーネントツリーがクライアントサイドでレンダリングされます。

これにより、ルートの一部を静的にレンダリングしながら、useSearchParamsを使用する動的な部分をクライアントサイドでレンダリングできます。

useSearchParamsを使用するクライアントコンポーネントを<Suspense/>境界でラップすることをお勧めします。これにより、その上位のクライアントコンポーネントを静的にレンダリングし、初期のHTMLの一部として送信できます。

例:

app/dashboard/search-bar.tsx
TypeScript
'use client'
 
import { useSearchParams } from 'next/navigation'
 
export default function SearchBar() {
  const searchParams = useSearchParams()
 
  const search = searchParams.get('search')
 
  // 静的レンダリングを使用する場合、これはサーバー上でログに記録されません
  console.log(search)
 
  return <>Search: {search}</>
}
app/dashboard/page.tsx
TypeScript
import { Suspense } from 'react'
import SearchBar from './search-bar'
 
// Suspense境界に渡されるこのコンポーネントは、
// 初期のHTMLで検索バーの代わりにレンダリングされます。
// React hydration中に値が利用可能になると、
// フォールバックは`<SearchBar>`コンポーネントに置き換えられます。
function SearchBarFallback() {
  return <>placeholder</>
}
 
export default function Page() {
  return (
    <>
      <nav>
        <Suspense fallback={<SearchBarFallback />}>
          <SearchBar />
        </Suspense>
      </nav>
      <h1>Dashboard</h1>
    </>
  )
}

動的レンダリング

ルートが動的にレンダリングされる場合、useSearchParamsはクライアントコンポーネントの初期サーバーレンダリング中にサーバー上で利用可能になります。

例:

app/dashboard/search-bar.tsx
TypeScript
'use client'
 
import { useSearchParams } from 'next/navigation'
 
export default function SearchBar() {
  const searchParams = useSearchParams()
 
  const search = searchParams.get('search')
 
  // これは初期レンダリング時にサーバー上でログに記録され、
  // その後のナビゲーション時にクライアント上でログに記録されます。
  console.log(search)
 
  return <>Search: {search}</>
}
app/dashboard/page.tsx
TypeScript
import SearchBar from './search-bar'
 
export const dynamic = 'force-dynamic'
 
export default function Page() {
  return (
    <>
      <nav>
        <SearchBar />
      </nav>
      <h1>Dashboard</h1>
    </>
  )
}

補足: dynamic ルートセグメント設定オプションforce-dynamic に設定することで、動的レンダリングを強制できます。

サーバーコンポーネント

ページ

ページ(サーバーコンポーネント)で検索パラメータにアクセスするには、searchParams プロップを使用します。

レイアウト

ページとは異なり、レイアウト(サーバーコンポーネント)は searchParams プロップを受け取りません。これは、共有レイアウトがナビゲーション中に再レンダリングされないため、ナビゲーション間で古い searchParams が発生する可能性があるためです。詳細な説明はこちらを参照してください。

代わりに、ページの searchParams プロップまたはクライアントコンポーネントの useSearchParams フックを使用します。これらは最新の searchParams を使用してクライアント側で再レンダリングされます。

searchParams の更新

useRouter または Link を使用して新しい searchParams を設定できます。ナビゲーションが実行された後、現在の page.js は更新された searchParams プロップを受け取ります。

app/example-client-component.tsx
TypeScript
'use client'
 
export default function ExampleClientComponent() {
  const router = useRouter()
  const pathname = usePathname()
  const searchParams = useSearchParams()
 
  // 現在の searchParams と提供されたキー/値のペアをマージして
  // 新しい searchParams 文字列を取得
  const createQueryString = useCallback(
    (name: string, value: string) => {
      const params = new URLSearchParams(searchParams.toString())
      params.set(name, value)
 
      return params.toString()
    },
    [searchParams]
  )
 
  return (
    <>
      <p>並び順</p>
 
      {/* useRouter を使用 */}
      <button
        onClick={() => {
          // <pathname>?sort=asc
          router.push(pathname + '?' + createQueryString('sort', 'asc'))
        }}
      >
        昇順
      </button>
 
      {/* <Link> を使用 */}
      <Link
        href={
          // <pathname>?sort=desc
          pathname + '?' + createQueryString('sort', 'desc')
        }
      >
        降順
      </Link>
    </>
  )
}

バージョン履歴

バージョン変更点
v13.0.0useSearchParams が導入されました。