useLinkStatus
useLinkStatus
フックは、<Link>
のpending状態を追跡することができます。これを使用して、新しいルートへのナビゲーションが完了するまでの間、ユーザーにインラインの視覚的フィードバック(スピナーやテキストのきらめきなど)を表示することができます。
useLinkStatus
が役立つのは以下の場合です:
- Prefetching が無効化されているか、進行中でナビゲーションがブロックされている場合
- 目的地のルートが動的で、即時ナビゲーションを可能にする
loading.js
ファイルが含まれていない場合
- TypeScript
- JavaScript
app/loading-indicator.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
}
app/loading-indicator.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
}
- TypeScript
- JavaScript
app/header.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>
)
}
app/header.js
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
コンポーネントの子孫コンポーネント内で使用する必要があります- このフックは、
Link
コンポーネントにprefetch={false}
が設定されている場合に最も有用です- リンクされたルートが事前取得されている場合、pending 状態はスキップされます
- 短時間で複数のリンクをクリックした場合、最後のリンクの pending 状態のみが表示されます
- このフックは Pages Router ではサポートされておらず、常に
{ pending: false }
を返します
パラメータ
const { pending } = useLinkStatus()
useLinkStatus
はパラメータを受け取りません。
戻り値
useLinkStatus
は、1つのプロパティを持つオブジェクトを返します:
プロパティ | 型 | 説明 |
---|---|---|
pending | boolean | 履歴が更新される前は true 、更新後は false |
例
インラインのローディングインジケーター
ユーザーが事前取得が完了する前にリンクをクリックした場合、ナビゲーションが行われていることを示す視覚的フィードバックを追加することは有用です。
- TypeScript
- JavaScript
app/components/loading-indicator.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
}
app/components/loading-indicator.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
}
- TypeScript
- JavaScript
app/shop/layout.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>
)
}
app/shop/layout.js
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
)として開始することです。
app/styles/global.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 が導入されました。 |