useLinkStatus
useLinkStatus
鉤子可讓您追蹤 <Link>
的 pending 狀態。您可以使用它在使用者導航到新路由時顯示內嵌的視覺回饋(例如旋轉圖示或文字閃爍)。
useLinkStatus
在以下情況特別有用:
- 預取 (Prefetching) 被禁用或正在進行中,導致導航被阻擋
- 目標路由是動態路由 且 沒有包含
loading.js
檔案來實現即時導航
'use client'
import { useLinkStatus } from 'next/link'
export default function LoadingIndicator() {
const { pending } = useLinkStatus()
return pending ? (
<div role="status" aria-label="Loading" className="spinner" />
) : null
}
'use client'
import { useLinkStatus } from 'next/link'
export default function LoadingIndicator() {
const { pending } = useLinkStatus()
return pending ? (
<div role="status" aria-label="Loading" className="spinner" />
) : null
}
import Link from 'next/link'
import LoadingIndicator from './loading-indicator'
export default function Header() {
return (
<header>
<Link href="/dashboard" prefetch={false}>
Dashboard <LoadingIndicator />
</Link>
</header>
)
}
import Link from 'next/link'
import LoadingIndicator from './loading-indicator'
export default function Header() {
return (
<header>
<Link href="/dashboard" prefetch={false}>
Dashboard <LoadingIndicator />
</Link>
</header>
)
}
重要須知:
useLinkStatus
必須在Link
元件的子元件中使用- 當
Link
元件設定prefetch={false}
時,此鉤子最為有用- 如果連結路由已被預取,pending 狀態將被跳過
- 當快速連續點擊多個連結時,只會顯示最後一個連結的 pending 狀態
- 此鉤子在 Pages Router 中不受支援,將始終返回
{ pending: false }
參數
const { pending } = useLinkStatus()
useLinkStatus
不接受任何參數。
返回值
useLinkStatus
返回一個包含單一屬性的物件:
屬性 | 類型 | 描述 |
---|---|---|
pending | boolean | 歷史更新前為 true ,更新後為 false |
範例
內嵌載入指示器
當使用者在預取完成前點擊連結時,添加視覺回饋有助於提示導航正在進行中。
'use client'
import { useLinkStatus } from 'next/link'
export default function LoadingIndicator() {
const { pending } = useLinkStatus()
return pending ? (
<div role="status" aria-label="Loading" className="spinner" />
) : null
}
'use client'
import { useLinkStatus } from 'next/link'
export default function LoadingIndicator() {
const { pending } = useLinkStatus()
return pending ? (
<div role="status" aria-label="Loading" className="spinner" />
) : null
}
import Link from 'next/link'
import LoadingIndicator from './components/loading-indicator'
const links = [
{ href: '/shop/electronics', label: 'Electronics' },
{ href: '/shop/clothing', label: 'Clothing' },
{ href: '/shop/books', label: 'Books' },
]
function Menubar() {
return (
<div>
{links.map((link) => (
<Link key={link.label} href={link.href}>
{link.label} <LoadingIndicator />
</Link>
))}
</div>
)
}
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div>
<Menubar />
{children}
</div>
)
}
import Link from 'next/link'
import LoadingIndicator from './components/loading-indicator'
const links = [
{ href: '/shop/electronics', label: 'Electronics' },
{ href: '/shop/clothing', label: 'Clothing' },
{ href: '/shop/books', label: 'Books' },
]
function Menubar() {
return (
<div>
{links.map((link) => (
<Link key={link.label} href={link.href}>
{link.label} <LoadingIndicator />
</Link>
))}
</div>
)
}
export default function Layout({ children }) {
return (
<div>
<Menubar />
{children}
</div>
)
}
優雅處理快速導航
如果導航到新路由的速度很快,使用者可能會看到不必要的載入指示器閃爍。一種改善使用者體驗的方法是添加初始動畫延遲(例如 100ms)並以不可見狀態(例如 opacity: 0
)開始動畫,這樣只有在導航耗時較長時才會顯示載入指示器。
.spinner {
/* ... */
opacity: 0;
animation:
fadeIn 500ms 100ms forwards,
rotate 1s linear infinite;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes rotate {
to {
transform: rotate(360deg);
}
}
版本 | 變更 |
---|---|
v15.3.0 | 新增 useLinkStatus 鉤子 |