useLinkStatus
useLinkStatus
フックを使用すると、<Link>
の 保留中 (pending) 状態を追跡できます。新しいルートへのナビゲーションが完了するまでの間、ユーザーに対してインラインの視覚的フィードバック(スピナーやテキストのグリマーなど)を表示するのに使用できます。
useLinkStatus
が有用なケース:
- プリフェッチ が無効化されているか進行中で、ナビゲーションがブロックされている場合
- 遷移先ルートが動的 かつ 即時ナビゲーションを可能にする
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}
が設定されている場合に最も有用です- リンク先ルートがプリフェッチされている場合、保留中状態はスキップされます
- 複数のリンクを素早く連続してクリックした場合、最後のリンクの保留中状態のみが表示されます
- このフックは 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>
)
}
高速ナビゲーションの適切な処理
新しいルートへのナビゲーションが高速な場合、ユーザーは不要なローディングインジケーターの点滅を見る可能性があります。ユーザーエクスペリエンスを向上させ、ナビゲーションに時間がかかる場合にのみローディングインジケーターを表示する方法の1つは、初期アニメーション遅延(例: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 が導入されました |