メインコンテンツまでスキップ

useSearchParams

useSearchParamsは、現在の URL のクエリ文字列を読み取るためのClient Componentのフックです。

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

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}</>
}

Parameters

const searchParams = useSearchParams()

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

Returns

useSearchParamsURLSearchParamsインターフェースの読み取り専用バージョンを返し、これには、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
  • URLSearchParamsのその他の読み取り専用メソッドについては、 getAll(), keys(), values(), entries(), forEach() および toString() を参照してください。

Good to know:

  • useSearchParamsClient Componentのフックであり、部分レンダリング中に値が古くなるのを防ぐために、Server Componentsではサポートされていません
  • アプリケーションが/pagesディレクトリを含む場合、useSearchParamsReadonlyURLSearchParams | nullを返します。getServerSidePropsを使用していないページのプリレンダリング中にクエリパラメータを知ることができないためです。

Behavior

Static Rendering

ルートが静的にレンダリングされる場合、useSearchParams()を呼び出すと、もっとも近いサスペンス境界(Suspense boundary)までのツリーがクライアント側でレンダリングされます。

これにより、ページの一部は静的にレンダリングされ、searchParamsを使用する動的な部分はクライアント側でレンダリングされます。

useSearchParamsを使用するコンポーネントをサスペンス境界(Suspense boundary)でラップすることで、クライアント側でレンダリングされるルート部分を減らすことができます。例えば:

app/dashboard/search-bar.tsx
'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
import { Suspense } from 'react'
import SearchBar from './search-bar'

// このコンポーネントは、サスペンス境界(Suspense boundary)にフォールバックとして渡され、初期HTMLでは検索バーの代わりにレンダリングされます
// Reactのハイドレーション中に値が利用可能になると、フォールバックは<SearchBar>コンポーネントに置き換えられます
function SearchBarFallback() {
return <>placeholder</>
}

export default function Page() {
return (
<>
<nav>
<Suspense fallback={<SearchBarFallback />}>
<SearchBar />
</Suspense>
</nav>
<h1>Dashboard</h1>
</>
)
}

Dynamic Rendering

ルートが動的にレンダリングされる場合、useSearchParamsは Client Component の初回サーバーレンダリング時にサーバー上で利用可能になります。

Good to know: 動的ルートsegmentの設定オプションforce-dynamicに設定することで、dynamic rendering を強制することができます。

例:

app/dashboard/search-bar.tsx
'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
import SearchBar from './search-bar'

export const dynamic = 'force-dynamic'

export default function Page() {
return (
<>
<nav>
<SearchBar />
</nav>
<h1>Dashboard</h1>
</>
)
}

Server Components

Pages

Pages(Server Components)でクエリパラメータにアクセスするには、searchParamsプロップを使用します。

Layouts

Pages とは異なり、Layouts(Server Components)はsearchParamsプロップを受け取りません。これは、共有レイアウトがナビゲーション中に再レンダリングされないため、ナビゲーション間で古いsearchParamsが表示される可能性があるためです。詳しい説明を見る。

その代わりに、Page のsearchParamsプロップ、または Client Component のuseSearchParamsフックを使用します。これらは、クライアント上で最新のsearchParamsと共に再レンダリングされます。

searchParamsの更新

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

app/example-client-component.tsx
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)
params.set(name, value)

return params.toString()
},
[searchParams]
)

return (
<>
<p>Sort By</p>

{/* useRouterを使用します */}
<button
onClick={() => {
// <pathname>?sort=asc
router.push(pathname + '?' + createQueryString('sort', 'asc'))
}}
>
ASC
</button>

{/* <Link>を使用します */}
<Link
href={
// <pathname>?sort=desc
pathname + '?' + createQueryString('sort', 'desc')
}
>
DESC
</Link>
</>
)
}

Version 履歴

VersionChanges
v13.0.0useSearchParams 導入