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 查詢字串的實用方法:
-
URLSearchParams.get()
: 返回與搜尋參數關聯的第一個值。例如:URL searchParams.get("a")
/dashboard?a=1
'1'
/dashboard?a=
''
/dashboard?b=3
null
/dashboard?a=1&a=2
'1'
- 使用getAll()
可獲取所有值 -
URLSearchParams.has()
: 返回一個布林值,表示給定參數是否存在。例如:URL searchParams.has("a")
/dashboard?a=1
true
/dashboard?b=3
false
-
了解更多關於
URLSearchParams
的其他**唯讀 (read-only)**方法,包括getAll()
、keys()
、values()
、entries()
、forEach()
和toString()
。
須知:
useSearchParams
是一個客戶端元件 (Client Component) 鉤子,不支援在伺服器元件 (Server Components) 中使用,以避免在部分渲染 (partial rendering) 期間出現過時的值。- 如果應用程式包含
/pages
目錄,useSearchParams
會返回ReadonlyURLSearchParams | null
。null
值是為了在遷移期間保持兼容性,因為在不使用getServerSideProps
的頁面預渲染期間無法知道搜尋參數。
靜態渲染 (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 水合 (hydration) 期間值可用時,
// 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 水合 (hydration) 期間值可用時,
// 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
你可以使用 useRouter
或 Link
來設置新的 searchParams
。執行導航後,當前的 page.js
將接收更新的 searchParams
屬性。
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>
</>
)
}
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 。 |