Next.jsのチュートリアルをやってみる【ページ間の移動編】

前回

Next.jsのチュートリアルをやってみる【レイアウトとページ編】

はじめに

前回はダッシュボードのレイアウトとページを作成しました。今回はユーザーがダッシュボードのルート間をナビゲートできるようにリンクを追加していきます。

ナビゲーションを最適化する理由

ページ間のリンクにはHTML要素である<a>タグを使用することができます。すでにサイドバーのリンクには<a>タグを使用していますので、実際にクリックして移動してみましょう。

クリックすると全ページが更新されていることが分かります。

<Link> コンポーネント

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はリンク先のリートのコードをバックグラウンドで自動的にプリフェッチします。ユーザーがリンクをクリックするころには、リンク先のページのコードはすでにバックグラウンドで読み込まれているのです。

さらに詳しく知りたい方は公式ドキュメントの「Linking and Navigating」のHow Routing and Navigation Works」セクションを確認してください。

問題1

本番環境で、コンポーネントがブラウザのビューポートに表示されたとき、Next.jsは何をしますか?

  1. 追加CSSのダウンロード
  2. 画像のプリロード
  3. リンクされたルートのコードをプリフェッチする。
  4. リンクされたルートの遅延ロードを有効にする

3. リンクされたルートのコードをプリフェッチする。

Next.jsはリンク先のコードをバックグラウンドで自動的にプリフェッチします。 ユーザーがリンクをクリックするころには、リンク先ページのコードはすでにバックグラウンドで読み込まれています。

パターン:アクティブリンクの表示

一般的なUIパターンは、ユーザーが現在どのページにいるのかを示すために、アクティブなリンクを表示するというパターンです。このパターンを追加するにはURLからユーザーの現在のパスを取得する必要があります。Next.jsにはusePathname()というフックが用意されているので、それを使ってパスをチェックしこのパターンを実装することができます。

usePathname()はフックなので、nav-links.tsxをクライアント・コンポーネントにする必要があります。ファイルの先頭に'use client'ディレクティブを追加し、next/navigationからusePathname()をインポートします。

コードを以下のように変更しましょう。

/app/ui/dashboard/nav-links.tsx
'use client';
 
import {
  UserGroupIcon,
  HomeIcon,
  InboxIcon,
} 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();
  // ...
}

CSS編で紹介したclsxライブラリを使用すれば、リンクがアクティブなときに条件付きでクラス名を運用できます。link.hrefがパス名と一致するとき、リンクは青いテキストと水色の背景で表示されるようになります。

最終的にはこの用意なりました。

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

サーバーが起動されていることを確認し、改めて確認してみましょう。

まとめ

  • ページ間の移動で使用するナビゲーションは<a>タグと<Link>コンポーネントを使用することが可能
    • <a>タグは通常のページ遷移となる。
    • <Link >コンポーネントはクライアントサイド・ナビゲーションとなる。ページすべてではなく、部分的な遷移となる。
    • <Link>コンポーネントはルートセグメントごとにアプリケーションを分割するため、一部にエラーが起きても残りの部分は動作し続ける。
    • 本番環境で<Link>コンポーネントを使用すると、リンク先のルートをプリフェッチするため、ユーザーがリンクをクリックするころには、すでにリンク先のコードが読み込まれている。

次回

Next.jsのチュートリアルをやってみる【データベースの設定編】

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です