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) 之間的樹狀結構在客戶端渲染。
這允許頁面的一部分靜態渲染,同時使用 searchParams
的動態部分在客戶端渲染。
你可以通過將使用 useSearchParams
的元件包裹在 Suspense
邊界中,來減少客戶端渲染的路由部分。例如:
'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
會在客戶端元件的初始伺服器渲染期間於伺服器上可用。
須知事項: 將
dynamic
路由區段配置選項設為force-dynamic
可用於強制動態渲染。
例如:
'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>
</>
)
}
伺服器元件 (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)
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 。 |