5
チャプター5
ページ間の移動
前のチャプターでは、ダッシュボードのレイアウトとページを作成しました。次に、ユーザーがダッシュボードのルート間を移動できるようにリンクを追加しましょう。
このチャプターでは...
以下が取り上げるトピックです
next/link
コンポーネントの使い方。
usePathname()
フックを使用してアクティブなリンクを表示する方法。
Next.jsでのナビゲーションの仕組み。
なぜナビゲーションを最適化するのか?
ページ間をリンクするには、従来は<a>
HTML要素を使用していました。現在、サイドバーのリンクは<a>
要素を使用していますが、ブラウザでホーム、インボイス、顧客のページ間を移動するとどうなるか見てみましょう。
気づきましたか?
ページを移動するたびにフルページリフレッシュが発生しています!
<Link>
コンポーネント
Next.jsでは、アプリケーション内のページ間をリンクするために<Link />
コンポーネントを使用できます。<Link>
を使用すると、JavaScriptでクライアントサイドナビゲーションを行うことができます。
<Link />
コンポーネントを使用するには、/app/ui/dashboard/nav-links.tsx
を開き、next/link
からLink
コンポーネントをインポートします。次に、<a>
タグを<Link>
に置き換えます。
import {
UserGroupIcon,
HomeIcon,
DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
// ...
export default function NavLinks() {
return (
<>
{links.map((link) => {
const LinkIcon = link.icon;
return (
<Link
key={link.name}
href={link.href}
className="flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3"
>
<LinkIcon className="w-6" />
<p className="hidden md:block">{link.name}</p>
</Link>
);
})}
</>
);
}
ご覧のとおり、Link
コンポーネントは<a>
タグの使用に似ていますが、<a href="…">
の代わりに<Link href="…">
を使用します。
変更を保存し、ローカルホストで動作するか確認してください。これで、フルリフレッシュなしでページ間を移動できるようになるはずです。アプリケーションの一部はサーバーでレンダリングされますが、フルページリフレッシュがないため、まるでネイティブのウェブアプリのように感じられます。なぜそうなるのでしょうか?
自動コード分割とプリフェッチ
ナビゲーション体験を向上させるため、Next.jsはルートセグメントごとにアプリケーションを自動的にコード分割します。これは、ブラウザが初期ページロード時にアプリケーションコードのすべてを読み込む従来のReact SPAとは異なります。
ルートごとにコードを分割すると、ページが隔離されます。特定のページでエラーが発生しても、アプリケーションの残りの部分は引き続き動作します。また、ブラウザが解析するコードが少なくなるため、アプリケーションが高速になります。
さらに、プロダクション環境では、ブラウザのビューポートに<Link>
コンポーネントが表示されると、Next.jsはバックグラウンドでリンクされたルートのコードを自動的にプリフェッチします。ユーザーがリンクをクリックする頃には、目的のページのコードはすでにバックグラウンドで読み込まれているため、ページの遷移がほぼ瞬時に行われます!
ナビゲーションの仕組みについて詳しく学ぶ。
パターン: アクティブなリンクの表示
一般的なUIパターンとして、ユーザーが現在どのページにいるかを示すためにアクティブなリンクを表示します。これを行うには、URLからユーザーの現在のパスを取得する必要があります。Next.jsは、パスをチェックし、このパターンを実装するために使用できるusePathname()
と呼ばれるフックを提供しています。
usePathname()
はReactフックであるため、nav-links.tsx
をクライアントコンポーネントにする必要があります。ファイルの先頭にReactの"use client"
ディレクティブを追加し、next/navigation
からusePathname()
をインポートしてください。
'use client';
import {
UserGroupIcon,
HomeIcon,
DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
// ...
次に、<NavLinks />
コンポーネント内でパスをpathname
という変数に割り当てます。
export default function NavLinks() {
const pathname = usePathname();
// ...
}
注:
nav-links.tsx
はNext.jsにとって特別なファイルではありません。好きな名前を付けることができます。もし名前を変更する場合は、それに応じてインポートステートメントを更新してください。
リンクがアクティブなときに条件付きでクラス名を適用するために、CSSスタイリングの章で紹介されたclsx
ライブラリを使用できます。link.href
がpathname
と一致する場合、リンクは青いテキストと薄い青の背景で表示されるべきです。
以下はnav-links.tsx
の最終コードです
'use client';
import {
UserGroupIcon,
HomeIcon,
DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import clsx from 'clsx';
// ...
export default function NavLinks() {
const pathname = usePathname();
return (
<>
{links.map((link) => {
const LinkIcon = link.icon;
return (
<Link
key={link.name}
href={link.href}
className={clsx(
'flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3',
{
'bg-sky-100 text-blue-600': pathname === link.href,
},
)}
>
<LinkIcon className="w-6" />
<p className="hidden md:block">{link.name}</p>
</Link>
);
})}
</>
);
}
保存してローカルホストを確認してください。これで、アクティブなリンクが青色で強調表示されているのがわかるはずです。
チャプターを完了しました5
Next.jsでページ間をリンクし、クライアントサイドナビゲーションを活用する方法を学びました。
この情報は役に立ちましたか?