これは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>コンポーネントへ置き換えます
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
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ライブラリでアクティブなリンクをサイドバー上で青色に変える
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
'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 にアクセスします。
サイドバーをクリックしてページ遷移してみると、クリックした部分が青色で強調されます!
次章のメモ
コメント