コンテンツへスキップ

5

ページ間の移動

前のチャプターでは、ダッシュボードのレイアウトとページを作成しました。次に、ユーザーがダッシュボードのルート間を移動できるようにリンクを追加しましょう。

このチャプターでは...

以下が取り上げるトピックです

next/link コンポーネントの使い方。

usePathname() フックを使用してアクティブなリンクを表示する方法。

Next.jsでのナビゲーションの仕組み。

なぜナビゲーションを最適化するのか?

ページ間をリンクするには、従来は<a> HTML要素を使用していました。現在、サイドバーのリンクは<a>要素を使用していますが、ブラウザでホーム、インボイス、顧客のページ間を移動するとどうなるか見てみましょう。

気づきましたか?

ページを移動するたびにフルページリフレッシュが発生しています!

Next.jsでは、アプリケーション内のページ間をリンクするために<Link />コンポーネントを使用できます。<Link>を使用すると、JavaScriptでクライアントサイドナビゲーションを行うことができます。

<Link />コンポーネントを使用するには、/app/ui/dashboard/nav-links.tsxを開き、next/linkからLinkコンポーネントをインポートします。次に、<a>タグを<Link>に置き換えます。

/app/ui/dashboard/nav-links.tsx
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()をインポートしてください。

/app/ui/dashboard/nav-links.tsx
'use client';
 
import {
  UserGroupIcon,
  HomeIcon,
  DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
 
// ...

次に、<NavLinks />コンポーネント内でパスをpathnameという変数に割り当てます。

/app/ui/dashboard/nav-links.tsx
export default function NavLinks() {
  const pathname = usePathname();
  // ...
}

: nav-links.tsxはNext.jsにとって特別なファイルではありません。好きな名前を付けることができます。もし名前を変更する場合は、それに応じてインポートステートメントを更新してください。

リンクがアクティブなときに条件付きでクラス名を適用するために、CSSスタイリングの章で紹介されたclsxライブラリを使用できます。link.hrefpathnameと一致する場合、リンクは青いテキストと薄い青の背景で表示されるべきです。

以下はnav-links.tsxの最終コードです

/app/ui/dashboard/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でページ間をリンクし、クライアントサイドナビゲーションを活用する方法を学びました。

次へ

6: データベースのセットアップ

実際のデータをフェッチするためにデータベースを作成しましょう!