【5章】Next.jsのチュートリアルをやってみた
これはNext.js の公式チュートリアルの5. Navigating Between Pagesにやってみたメモです
前章のメモ
Next.js の公式チュートリアルの該当ページ
学ぶこと
- next/linkコンポーネントの使い方
- usePathname() フックを使用したアクティブなリンクの表示
- Next.js 内でのナビゲーションの動き
<Link>コンポーネント
Next.js では**<Link>コンポーネントを使用してリンクを表示させる**ことができます。
実際に使ってみて理解を深めていきましょう!
/app/ui/dashboard/nav-links.tsxでLink コンポーネントをインポートします。
そして、<a>タグを<Link>コンポーネントへ置き換えます
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 コンポーネントを含むページを表示した際に
リンク先のページをバックグラウンドで読み込んで(プリフェッチ)クライアント側でキャッシュしておきます。
実際に遷移するときにはキャッシュから読み込み、画面全体ではなく対象の部分のみを再レンダリングします。
この仕組みによって、画面がリロードされず瞬時に遷移することができます
詳しいナビゲーションの仕組みは ↓ のドキュメントをご覧ください
アクティブなリンクを表示する
一般的なアプリではアクティブリンク(どのページにいるのか)を表示します。
URL からユーザーのパスを取得する必要があり、Next.js では**usePathname()**を使います
/app/ui/dashboard/nav-links.tsxで実際に使ってみましょう
実装方針としては、
- usePathname() はフックなので、サーバコンポーネント ⇒ クライアントコンポーネントへ変更するために、1 行目に 'use client'; を追加する
- usePathnameをインポートする
- パスを変数にいれる
- clsx ライブラリでアクティブなリンクをサイドバー上で青色に変える
+'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 にアクセスします。
サイドバーをクリックしてページ遷移してみると、クリックした部分が青色で強調されます!
次章のメモ
Discussion