主题
useLinkStatus
useLinkStatus
钩子允许你跟踪 <Link>
的待处理状态。你可以使用它在导航到新路由完成时向用户显示内联视觉反馈(例如旋转图标或文本闪烁)。
¥The useLinkStatus
hook lets you tracks the pending state of a <Link>
. You can use it to show inline visual feedback to the user (like spinners or text glimmers) while a navigation to a new route completes.
useLinkStatus
在以下情况下有用:
¥useLinkStatus
is useful when:
预请求 已禁用或正在运行,这意味着导航被阻止。
¥Prefetching is disabled or in progress meaning navigation is blocked.
目标路由是动态的,不包含允许即时导航的
loading.js
文件。¥The destination route is dynamic and doesn't include a
loading.js
file that would allow an instant navigation.
tsx
'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
}
jsx
'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
}
tsx
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>
)
}
jsx
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>
)
}
需要了解:
¥Good to know:
useLinkStatus
必须在Link
组件的后代组件中使用¥
useLinkStatus
must be used within a descendant component of aLink
component当
prefetch={false}
设置在Link
组件上时,此钩子最有用。¥The hook is most useful when
prefetch={false}
is set on theLink
component如果链接的路由已预取,则将跳过待处理状态。
¥If the linked route has been prefetched, the pending state will be skipped
快速连续点击多个链接时,仅显示最后一个链接的待处理状态。
¥When clicking multiple links in quick succession, only the last link's pending state is shown
Pages Router 不支持此钩子,并且始终返回
{ pending: false }
。¥This hook is not supported in the Pages Router and will always return
{ pending: false }
参数
¥Parameters
tsx
const { pending } = useLinkStatus()
useLinkStatus
不带任何参数。
¥useLinkStatus
does not take any parameters.
返回
¥Returns
useLinkStatus
返回一个具有单个属性的对象:
¥useLinkStatus
returns an object with a single property:
属性 | 类型 | 描述 |
---|---|---|
pending | boolean | true 在历史记录更新之前,false 在历史记录更新之后 |
示例
¥Example
内联加载指示器
¥Inline loading indicator
如果用户在预加载完成之前点击链接,添加导航正在进行的视觉反馈会很有帮助。
¥It's helpful to add visual feedback that navigation is happening in case the user clicks a link before prefetching is complete.
tsx
'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
}
jsx
'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
}
tsx
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>
)
}
jsx
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>
)
}
优雅地处理快速导航
¥Gracefully handling fast navigation
如果导航到新路由的速度很快,用户可能会看到不必要的加载指示器闪烁。一种改善用户体验并仅在导航需要时间完成时显示加载指示器的方法是添加初始动画延迟(例如 100 毫秒),并将动画设置为不可见(例如 opacity: 0
)。
¥If the navigation to a new route is fast, users may see an unecessary flash of the loading indicator. One way to improve the user experience and only show the loading indicator when the navigation takes time to complete is to add an initial animation delay (e.g. 100ms) and start the animation as invisible (e.g. opacity: 0
).
css
.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 已引入。 |