🐷

Next.js Learn Course をやってみる Chapter4

2023/10/28に公開

レイアウトとページの作成

https://nextjs.org/learn/dashboard-app/creating-layouts-and-pages

💡 ここがApp Routerで変わった事が一番よくわかるかなーと思い、先にやりましたが、後から見てみるとChapter3の内容を記述しないとコンパイルエラーになるので、順番にやってください。

このチャプターでやること

  • ファイルシステムのルーティングを使って、/login, dashboardのページを作成
  • 新しいルートを作るときのフォルダとファイルの役割の理解
  • 複数のダッシュボードページの間で共有されるレイアウトの作成
  • colocation, partial rendering, root layoutの理解

ネストされたルーティング

Next.jsではフォルダに置かれたファイルの構造がそのままWebページのパスと一致します。

  • app
    • dashboard
      • invoices

acme.com / dashboard /invoices

以前まではpagesフォルダでしたが、app routerだとルートはappフォルダになるみたいですね。

page.tsxはルートのためのUIを含んだReactコンポーネントexportする特別なNext.jsのファイルになります。

/app/page.tsxはドメイン直下のホームページを表示するファイルになります。

フォルダのネストがそのままURLと一致するので、ログインページ (あなたのドメイン/login)を作る場合は、/app/login/page.tsx を作成します。

ダッシュボードのページを作る

app / dashboard / page.tsxを作成し、以下のコードを書く。

export default function Page() {
  return <p>Dashboard Page</p>;
}

これで http://localhost:3000/dashboard に行くと上で書かれたテキストが表示されています。

特別な page ファイルを持つことによって、同じディレクトリにUIコンポーネントやテストファイルを置くことができます。pageファイル内のコンテントのみ公開されます。とても便利。

https://nextjs.org/docs/app/building-your-application/routing#colocation

レイアウトを作る

複数のページにまたがるレイアウトを作成します。例えば、上部にあるタブメニューなどはどのページにも出して欲しいですよね。

特別なファイルとして layout.tsx を使用します。

/dashboard / layout.tsxを作成し、以下のコードを書きます。

import SideNav from '@/app/ui/dashboard/sidenav';
 
export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <div className="flex h-screen flex-col md:flex-row md:overflow-hidden">
      <div className="w-full flex-none md:w-64">
        <SideNav />
      </div>
      <div className="flex-grow p-6 md:overflow-y-auto md:p-12">{children}</div>
    </div>
  );
}

Layoutコンポーネントは、 children propを受け取り、/dashboard配下にある全てのページは自動的にchildrenとして内部にネストされます。

Webサイトで共通で使いたいヘッダーやサイドメニューなどはLayout.tsxに書いておけば、全てのPageに適用されます。(上の例だとdashboardフォルダと並列に置いた場合は適用されないので、フォルダを確認)

レイアウトの利点は、ナビゲーション時に、ページコンポーネントだけが更新され、レイアウトは再レンダリングされないこと!(めっちゃ便利だけど、例えばサイドメニューに今いるページの場所を表示したいとかなるとどうなるんだろう)

これをPartial Renderingと呼びます。

Root Layout

/app/layout.tsx はルートレイアウトと呼びます。これは必須で、ここに追加したUIはアプリケーションの全てのページで共有されます。

ルートレイアウトを使って <html><body>タグを修正し、メタデータを追加できます。

import "@/app/ui/global.css";
import { inter } from "@/app/ui/fonts";
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={`${inter.className}`}>{children}</body>
    </html>
  );
}

削除すると怒られます。

Discussion