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="…">を使用します。
変更を保存し、ローカルホストで動作するか確認してください。ページ間をリフレッシュなしで移動できるようになっているはずです。アプリケーションの一部はサーバーでレンダリングされますが、ページ全体のリフレッシュがないため、ネイティブなWebアプリのように感じられます。なぜでしょうか?
自動コード分割とプリフェッチ
ナビゲーションエクスペリエンスを向上させるために、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でのクライアントサイドナビゲーションの活用方法を学びました。
役に立ちましたか?