Skip to content

useSearchParams

useSearchParams 是一个客户端组件钩子,可让你读取当前 URL 的查询字符串。

¥useSearchParams is a Client Component hook that lets you read the current URL's query string.

useSearchParams 返回 URLSearchParams 接口的只读版本。

¥useSearchParams returns a read-only version of the URLSearchParams interface.

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

tsx
const searchParams = useSearchParams()

useSearchParams 不带任何参数。

¥useSearchParams does not take any parameters.

返回

¥Returns

useSearchParams 返回 URLSearchParams 接口的只读版本,其中包括用于读取 URL 查询字符串的实用方法:

¥useSearchParams returns a read-only version of the URLSearchParams interface, which includes utility methods for reading the URL's query string:

需要了解:

¥Good to know:

  • useSearchParams客户端组件 钩子,在 服务器组件 中不受支持,以防止 部分渲染 期间的值过时。

    ¥useSearchParams is a Client Component hook and is not supported in Server Components to prevent stale values during partial rendering.

  • 如果应用包含 /pages 目录,则 useSearchParams 将返回 ReadonlyURLSearchParams | nullnull 值用于迁移期间的兼容性,因为在不使用 getServerSideProps 的页面预渲染期间无法知道搜索参数

    ¥If an application includes the /pages directory, useSearchParams will return ReadonlyURLSearchParams | null. The null value is for compatibility during migration since search params cannot be known during pre-rendering of a page that doesn't use getServerSideProps

行为

¥Behavior

静态渲染

¥Static Rendering

如果路由是 静态渲染,调用 useSearchParams 将导致客户端组件树(直到最近的 Suspense 边界)被客户端渲染。

¥If a route is statically rendered, calling useSearchParams will cause the Client Component tree up to the closest Suspense boundary to be client-side rendered.

这允许静态渲染路由的一部分,而使用 useSearchParams 的动态部分则在客户端渲染。

¥This allows a part of the route to be statically rendered while the dynamic part that uses useSearchParams is client-side rendered.

我们建议将使用 useSearchParams 的客户端组件封装在 <Suspense/> 边界中。这将允许其之上的任何客户端组件静态渲染并作为初始 HTML 的一部分发送。示例

¥We recommend wrapping the Client Component that uses useSearchParams in a <Suspense/> boundary. This will allow any Client Components above it to be statically rendered and sent as part of initial HTML. Example.

例如:

¥For example:

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

动态渲染

¥Dynamic Rendering

如果路由是 动态渲染,则在客户端组件的初始服务器渲染期间,useSearchParams 将在服务器上可用。

¥If a route is dynamically rendered, useSearchParams will be available on the server during the initial server render of the Client Component.

例如:

¥For example:

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

export const dynamic = 'force-dynamic'

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

export const dynamic = 'force-dynamic'

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

需要了解:将 dynamic 航段配置选项 设置为 force-dynamic 可用于强制动态渲染。

¥Good to know: Setting the dynamic route segment config option to force-dynamic can be used to force dynamic rendering.

服务器组件

¥Server Components

页面

¥Pages

要访问 页面(服务器组件)中的搜索参数,请使用 searchParams 属性。

¥To access search params in Pages (Server Components), use the searchParams prop.

布局

¥Layouts

与页面不同,布局(服务器组件)不接收 searchParams 属性。这是因为共享布局是 导航期间不重新渲染,这可能会导致导航之间的 searchParams 过时。查看 详细解释

¥Unlike Pages, Layouts (Server Components) do not receive the searchParams prop. This is because a shared layout is not re-rendered during navigation which could lead to stale searchParams between navigations. View detailed explanation.

相反,请在客户端组件中使用 Page searchParams 属性或 useSearchParams 钩子,该组件会使用最新的 searchParams 在客户端上重新渲染。

¥Instead, use the Page searchParams prop or the useSearchParams hook in a Client Component, which is re-rendered on the client with the latest searchParams.

示例

¥Examples

更新 searchParams

¥Updating searchParams

你可以使用 useRouterLink 来设置新的 searchParams。执行导航后,当前的 page.js 将收到更新的 searchParams 属性

¥You can use useRouter or Link to set new searchParams. After a navigation is performed, the current page.js will receive an updated searchParams prop.

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>
    </>
  )
}
jsx
'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, value) => {
      const params = new URLSearchParams(searchParams)
      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>
    </>
  )
}

版本历史

¥Version History

版本更改
v13.0.0useSearchParams 已引入。

Next.js v15.3 中文网 - 粤ICP备13048890号