コンテンツにスキップ

useSearchParams

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

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

app/dashboard/search-bar.tsx
'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 は、URLSearchParams インターフェースの **読み取り専用** バージョンを返します。これには、URL のクエリ文字列を読み取るためのユーティリティメソッドが含まれています。

  • 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
  • その他の読み取り専用メソッドについてURLSearchParamsgetAll()keys()values()entries()forEach()toString() など、詳細を確認してください。

知っておくと良いこと:

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

動作

静的レンダリング

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

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

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

例えば

app/dashboard/search-bar.tsx
'use client'
 
import { useSearchParams } from 'next/navigation'
 
export default function SearchBar() {
  const searchParams = useSearchParams()
 
  const search = searchParams.get('search')
 
  // This will not be logged on the server when using static rendering
  console.log(search)
 
  return <>Search: {search}</>
}
app/dashboard/page.tsx
import { Suspense } from 'react'
import SearchBar from './search-bar'
 
// This component passed as a fallback to the Suspense boundary
// will be rendered in place of the search bar in the initial HTML.
// When the value is available during React hydration the fallback
// will be replaced with the `<SearchBar>` component.
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
'use client'
 
import { useSearchParams } from 'next/navigation'
 
export default function SearchBar() {
  const searchParams = useSearchParams()
 
  const search = searchParams.get('search')
 
  // This will be logged on the server during the initial render
  // and on the client on subsequent navigations.
  console.log(search)
 
  return <>Search: {search}</>
}
app/dashboard/page.tsx
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 プロパティ、または最新の searchParams でクライアントで再レンダリングされるクライアントコンポーネントの useSearchParams フックを使用します。

searchParams の更新

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

app/example-client-component.tsx
'use client'
 
export default function ExampleClientComponent() {
  const router = useRouter()
  const pathname = usePathname()
  const searchParams = useSearchParams()
 
  // Get a new searchParams string by merging the current
  // searchParams with a provided key/value pair
  const createQueryString = useCallback(
    (name: string, value: string) => {
      const params = new URLSearchParams(searchParams.toString())
      params.set(name, value)
 
      return params.toString()
    },
    [searchParams]
  )
 
  return (
    <>
      <p>Sort By</p>
 
      {/* using useRouter */}
      <button
        onClick={() => {
          // <pathname>?sort=asc
          router.push(pathname + '?' + createQueryString('sort', 'asc'))
        }}
      >
        ASC
      </button>
 
      {/* using <Link> */}
      <Link
        href={
          // <pathname>?sort=desc
          pathname + '?' + createQueryString('sort', 'desc')
        }
      >
        DESC
      </Link>
    </>
  )
}

バージョン履歴

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