useSearchParams

useSearchParams 是一個 客戶端組件 (Client Component) 鉤子,用於讀取當前 URL 的 查詢字串 (query string)

useSearchParams 回傳 URLSearchParams 介面的 唯讀 (read-only) 版本。

'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}</>
}
'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 介面的 唯讀 (read-only) 版本,包含用於讀取 URL 查詢字串的實用方法:

須知事項:

行為

靜態渲染 (Static Rendering)

如果路由是 靜態渲染 (statically rendered),呼叫 useSearchParams 會導致客戶端組件樹向上到最近的 Suspense 邊界 (boundary) 被客戶端渲染。

這允許路由的一部分被靜態渲染,同時使用 useSearchParams 的動態部分被客戶端渲染。

我們建議將使用 useSearchParams 的客戶端組件包裹在 <Suspense/> 邊界中。這將允許其上方的任何客戶端組件被靜態渲染並作為初始 HTML 的一部分發送。範例

例如:

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

// 作為 Suspense 邊界的 fallback 傳遞的組件
// 將在初始 HTML 中代替搜尋欄呈現。
// 當 React 水合期間值可用時,fallback
// 將被 `<SearchBar>` 組件替換。
function SearchBarFallback() {
  return <>placeholder</>
}

export default function Page() {
  return (
    <>
      <nav>
        <Suspense fallback={<SearchBarFallback />}>
          <SearchBar />
        </Suspense>
      </nav>
      <h1>Dashboard</h1>
    </>
  )
}
import { Suspense } from 'react'
import SearchBar from './search-bar'

// 作為 Suspense 邊界的 fallback 傳遞的組件
// 將在初始 HTML 中代替搜尋欄呈現。
// 當 React 水合期間值可用時,fallback
// 將被 `<SearchBar>` 組件替換。
function SearchBarFallback() {
  return <>placeholder</>
}

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

動態渲染 (Dynamic Rendering)

如果路由是 動態渲染 (dynamically rendered)useSearchParams 將在客戶端組件的初始伺服器渲染期間在伺服器上可用。

例如:

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

export const dynamic = 'force-dynamic'

export default function Page() {
  return (
    <>
      <nav>
        <SearchBar />
      </nav>
      <h1>Dashboard</h1>
    </>
  )
}
import SearchBar from './search-bar'

export const dynamic = 'force-dynamic'

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

須知事項: 將 dynamic 路由段配置選項 設置為 force-dynamic 可用於強制動態渲染。

伺服器組件 (Server Components)

頁面 (Pages)

要在 頁面 (Pages)(伺服器組件)中訪問搜尋參數,請使用 searchParams 屬性。

佈局 (Layouts)

與頁面不同,佈局 (Layouts)(伺服器組件)不會接收 searchParams 屬性。這是因為共享佈局在 導航期間不會重新渲染,這可能導致導航之間的 searchParams 過時。查看 詳細解釋

相反,請在客戶端組件中使用頁面 searchParams 屬性或 useSearchParams 鉤子,這會在客戶端上使用最新的 searchParams 重新渲染。

範例

更新 searchParams

您可以使用 useRouterLink 來設置新的 searchParams。執行導航後,當前的 page.js 將接收更新的 searchParams 屬性

'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>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>
    </>
  )
}
'use client'

export default function ExampleClientComponent() {
  const router = useRouter()
  const pathname = usePathname()
  const searchParams = useSearchParams()

  // 通過將當前的 searchParams 與提供的鍵/值對合併
  // 來獲取新的 searchParams 字串
  const createQueryString = useCallback(
    (name, value) => {
      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>
    </>
  )
}

版本歷史

版本變更
v13.0.0引入 useSearchParams