メインコンテンツまでスキップ

useLinkStatus

useLinkStatus フックは、<Link>pending状態を追跡することができます。これを使用して、新しいルートへのナビゲーションが完了するまでの間、ユーザーにインラインの視覚的フィードバック(スピナーやテキストのきらめきなど)を表示することができます。

useLinkStatus が役立つのは以下の場合です:

  • Prefetching が無効化されているか、進行中でナビゲーションがブロックされている場合
  • 目的地のルートが動的で、即時ナビゲーションを可能にする loading.js ファイルが含まれていない場合
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/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>
)
}

Good to know:

  • useLinkStatusLink コンポーネントの子孫コンポーネント内で使用する必要があります
  • このフックは、Link コンポーネントに prefetch={false} が設定されている場合に最も有用です
  • リンクされたルートが事前取得されている場合、pending 状態はスキップされます
  • 短時間で複数のリンクをクリックした場合、最後のリンクの pending 状態のみが表示されます
  • このフックは Pages Router ではサポートされておらず、常に { pending: false } を返します

パラメータ

const { pending } = useLinkStatus()

useLinkStatus はパラメータを受け取りません。

戻り値

useLinkStatus は、1つのプロパティを持つオブジェクトを返します:

プロパティ説明
pendingboolean履歴が更新される前は true、更新後は false

インラインのローディングインジケーター

ユーザーが事前取得が完了する前にリンクをクリックした場合、ナビゲーションが行われていることを示す視覚的フィードバックを追加することは有用です。

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/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>
)
}

高速ナビゲーションの優雅な処理

新しいルートへのナビゲーションが速い場合、ユーザーは不要なローディングインジケーターのフラッシュを見ることがあります。ユーザーエクスペリエンスを向上させ、ナビゲーションが完了するのに時間がかかる場合にのみローディングインジケーターを表示するための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.0useLinkStatus が導入されました。