Skip to content

NextJS中文文档 - Use Search Params

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

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

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

参数

tsx
const searchParams = useSearchParams()

useSearchParams 不接受任何参数。

返回值

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

须知

  • useSearchParams 是一个客户端组件钩子,在服务器组件不支持,以防止在部分渲染期间出现过时的值。
  • 如果应用程序包含 /pages 目录,useSearchParams 将返回 ReadonlyURLSearchParams | null。对于不使用 getServerSideProps 的页面,在预渲染期间无法知道搜索参数,因此 null 值用于在迁移期间兼容。

行为

静态渲染

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

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

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

例如:

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

import { useSearchParams } from 'next/navigation'

export default function SearchBar() {
  const searchParams = useSearchParams()

  const search = searchParams.get('search')

  // 使用静态渲染时,这不会在服务器上记录
  console.log(search)

  return <>搜索: {search}</>
}
tsx
import { Suspense } from 'react'
import SearchBar from './search-bar'

// 这个作为 Suspense 边界的 fallback 传递的组件
// 将在初始 HTML 中替代搜索栏进行渲染。
// 当在 React 水合作用期间值可用时,fallback
// 将被 `<SearchBar>` 组件替换。
function SearchBarFallback() {
  return <>占位符</>
}

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

// 这个作为 Suspense 边界的 fallback 传递的组件
// 将在初始 HTML 中替代搜索栏进行渲染。
// 当在 React 水合作用期间值可用时,fallback
// 将被 `<SearchBar>` 组件替换。
function SearchBarFallback() {
  return <>占位符</>
}

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

动态渲染

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

例如:

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

import { useSearchParams } from 'next/navigation'

export default function SearchBar() {
  const searchParams = useSearchParams()

  const search = searchParams.get('search')

  // 这将在初始渲染期间在服务器上记录
  // 并在后续导航时在客户端上记录。
  console.log(search)

  return <>搜索: {search}</>
}
tsx
import SearchBar from './search-bar'

export const dynamic = 'force-dynamic'

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

export const dynamic = 'force-dynamic'

export default function Page() {
  return (
    <>
      <nav>
        <SearchBar />
      </nav>
      <h1>仪表盘</h1>
    </>
  )
}

须知:设置 dynamic 路由段配置选项force-dynamic 可用于强制动态渲染。

服务器组件

页面

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

布局

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

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

示例

更新 searchParams

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

tsx
'use client'

import { useCallback } from 'react'
import { useRouter, usePathname, useSearchParams } from 'next/navigation'
import Link from 'next/link'

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

import { useCallback } from 'react'
import { useRouter, usePathname, useSearchParams } from 'next/navigation'
import Link from 'next/link'

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>排序方式</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.0引入 useSearchParams

🎉有任何问题,欢迎联系我

WeChat QR Code
WeChat
QQ QR Code
QQ

赣ICP备2023003243号