💻

【5章】Next.jsのチュートリアルをやってみた

2025/01/06に公開

これはNext.js の公式チュートリアルの5. Navigating Between Pagesにやってみたメモです

前章のメモ

https://zenn.dev/kuuki/articles/nextjs-tutorial-04/

Next.js の公式チュートリアルの該当ページ

https://nextjs.org/learn/dashboard-app/navigating-between-pages

学ぶこと

  1. next/linkコンポーネントの使い方
  2. usePathname() フックを使用したアクティブなリンクの表示
  3. Next.js 内でのナビゲーションの動き

<Link>コンポーネント

Next.js では**<Link>コンポーネントを使用してリンクを表示させる**ことができます。

実際に使ってみて理解を深めていきましょう!

/app/ui/dashboard/nav-links.tsxでLink コンポーネントをインポートします。
そして、<a>タグを<Link>コンポーネントへ置き換えます

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

// Map of links to display in the side navigation.
// Depending on the size of the application, this would be stored in a database.
const links = [
  { name: 'Home', href: '/dashboard', icon: HomeIcon },
  {
    name: 'Invoices',
    href: '/dashboard/invoices',
    icon: DocumentDuplicateIcon,
  },
  { name: 'Customers', href: '/dashboard/customers', icon: UserGroupIcon },
];

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

npm run devでサーバを起動させ、http://localhost:3000/dashboard にアクセスします。

サイドバーをクリックしてページ遷移してみましょう!

ページがリロードされることなく、遷移していることがわかります
<a>タグを使用した場合は画面全体を更新して遷移するのでこれが<Link>コンポーネントの特徴になります。
コード上は<a>タグと<Link>コンポーネントは似ていますが、アプリ上の動きが異なるわけです

コード分割とプリフェッチ

Next.js ではファイルベースルーティングを採用しているため、ページとファイルが対応しています
各ページごとにコードが分割されており、特定のページのエラーが出てもアプリ全体に影響はありません。

また、コードが分割されていることで画面リロードなしの遷移も実現しています。
Link コンポーネントを含むページを表示した際に
リンク先のページをバックグラウンドで読み込んでプリフェッチ)クライアント側でキャッシュしておきます。

実際に遷移するときにはキャッシュから読み込み、画面全体ではなく対象の部分のみを再レンダリングします。
この仕組みによって、画面がリロードされず瞬時に遷移することができます

詳しいナビゲーションの仕組みは ↓ のドキュメントをご覧ください

https://nextjs.org/docs/app/building-your-application/routing/linking-and-navigating#how-routing-and-navigation-works

アクティブなリンクを表示する

一般的なアプリではアクティブリンク(どのページにいるのか)を表示します。
URL からユーザーのパスを取得する必要があり、Next.js では**usePathname()**を使います

/app/ui/dashboard/nav-links.tsxで実際に使ってみましょう

実装方針としては、

  1. usePathname() はフックなので、サーバコンポーネント ⇒ クライアントコンポーネントへ変更するために、1 行目に 'use client'; を追加する
  2. usePathnameをインポートする
  3. パスを変数にいれる
  4. clsx ライブラリでアクティブなリンクをサイドバー上で青色に変える
/app/ui/dashboard/nav-links.tsx
+'use client';

import {
  DocumentDuplicateIcon,
  HomeIcon,
  UserGroupIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
+import { usePathname } from 'next/navigation';
+import clsx from 'clsx';

// Map of links to display in the side navigation.
// Depending on the size of the application, this would be stored in a database.
const links = [
  { name: 'Home', href: '/dashboard', icon: HomeIcon },
  {
    name: 'Invoices',
    href: '/dashboard/invoices',
    icon: DocumentDuplicateIcon,
  },
  { name: 'Customers', href: '/dashboard/customers', icon: UserGroupIcon },
];

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

サーバを起動させ、http://localhost:3000/dashboard にアクセスします。

サイドバーをクリックしてページ遷移してみると、クリックした部分が青色で強調されます!

次章のメモ

https://zenn.dev/kuuki/articles/nextjs-tutorial-06/

Discussion