Next.jsで学ぶReact講座(完全初心者向け・30日)演習問題・課題 | 第3章:Next.jsらしさ – レイアウト

React Next.js
スポンサーリンク

この課題のねらい

この演習は「Next.js らしいレイアウト」の感覚をつかむことが目的です。
特に大事なのは、ページごとに毎回ヘッダーを書くのではなく、

共通ヘッダーを layout.tsx にまとめる
どのページを開いても同じヘッダーが表示される
必要ならフッターも同じように共通化する

という「レイアウトを一段上で管理する」という発想です。
ここがつかめると、一気に「アプリ全体をデザインする視点」に近づきます。


共通ヘッダー作成(layout.tsx の基本)

layout.tsx が担当する役割

Next.js(App Router)では、app/layout.tsx が「全ページ共通の枠」を担当します。
ブラウザでどの URL を開いても、

html や body の基本タグ
共通のヘッダー
共通の余白やフォント設定

などは、この layout.tsx に書かれた内容になります。
各ページ側(app/page.tsxapp/about/page.tsx)は、「中身だけ」を書くイメージです。

シンプルな layout.tsx の例

まずは、共通ヘッダーだけを持つ、最小限の layout.tsx を作ってみましょう。

// app/layout.tsx
import type { ReactNode } from "react";
import Link from "next/link";
import "./globals.css";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="ja">
      <body style={{ margin: 0, fontFamily: "sans-serif" }}>
        <header
          style={{
            padding: "12px 24px",
            borderBottom: "1px solid #e5e7eb",
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            backgroundColor: "white",
            position: "sticky",
            top: 0,
            zIndex: 10,
          }}
        >
          <div style={{ fontWeight: "bold" }}>Next.js × React 入門</div>

          <nav style={{ display: "flex", gap: "16px", fontSize: "14px" }}>
            <Link href="/">ホーム</Link>
            <Link href="/about">このサイトについて</Link>
          </nav>
        </header>

        <main style={{ padding: "24px" }}>{children}</main>
      </body>
    </html>
  );
}
TSX

ここでやっていることを整理します。

RootLayout コンポーネントは、すべてのページを包む「一番外側のコンポーネント」です。
header タグの中に、共通のタイトルとナビゲーションを定義しています。
main の中の {children} に、各ページの中身が挿し込まれます。

つまり、どのページを表示しても、

上にヘッダー(タイトル+リンク)
下にそのページ固有の内容

という構成になります。


layout.tsx を使ったページ側のシンプル化

ページファイルでは「中身だけ」に集中する

ヘッダーを layout.tsx に移したことで、ページ側のコードはとてもシンプルになります。
例えばトップページをこう書けます。

// app/page.tsx
export default function HomePage() {
  return (
    <>
      <h1>ホームページ</h1>
      <p>ここはトップページです。</p>
    </>
  );
}
TSX

ここでは main やヘッダーは一切書いていません。
なぜなら、それらはすでに layout.tsx に書いてあるからです。

layout.tsx<main>{children}</main>children の部分に、
この HomePage の JSX がそのまま入っていくイメージです。

同様に、app/about/page.tsx もこう書けます。

// app/about/page.tsx
export default function AboutPage() {
  return (
    <>
      <h1>このサイトについて</h1>
      <p>Next.js × React 入門講座のサンプルサイトです。</p>
    </>
  );
}
TSX

レイアウトのことは気にせず、「このページの中身は何か?」だけに集中できるのが、
layout.tsx を使う一番のメリットです。


フッター追加(挑戦課題)

ヘッダーと同じノリでフッターを追加する

次は、ヘッダーと同じようにフッターも共通化してみましょう。
やることはシンプルで、layout.tsx に footer を追加するだけです。

例として、先ほどの RootLayout を少しだけ拡張します。

// app/layout.tsx
import type { ReactNode } from "react";
import Link from "next/link";
import "./globals.css";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="ja">
      <body
        style={{
          margin: 0,
          fontFamily: "sans-serif",
          minHeight: "100vh",
          display: "flex",
          flexDirection: "column",
        }}
      >
        <header
          style={{
            padding: "12px 24px",
            borderBottom: "1px solid #e5e7eb",
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            backgroundColor: "white",
          }}
        >
          <div style={{ fontWeight: "bold" }}>Next.js × React 入門</div>

          <nav style={{ display: "flex", gap: "16px", fontSize: "14px" }}>
            <Link href="/">ホーム</Link>
            <Link href="/about">このサイトについて</Link>
          </nav>
        </header>

        <main style={{ padding: "24px", flex: 1 }}>{children}</main>

        <footer
          style={{
            padding: "12px 24px",
            borderTop: "1px solid #e5e7eb",
            fontSize: "12px",
            color: "#6b7280",
            backgroundColor: "white",
          }}
        >
          © {new Date().getFullYear()} Next.js × React 入門講座
        </footer>
      </body>
    </html>
  );
}
TSX

ここで大事なポイントは次の通りです。

body に minHeight: "100vh"display: "flex", flexDirection: "column" を指定しているので、画面全体が縦方向のフレックスレイアウトになります。
main に flex: 1 を付けているので、「中身部分」が空きスペースを埋め、フッターは常に一番下に張り付きやすくなります。
footer の中にコピーライトなどを入れておけば、どのページでも同じフッターが出ます。

これで、ヘッダーもフッターも「アプリ全体で共通」の状態になります。


レイアウト設計で意識してほしいこと

Next.js の layout.tsx を使うときに、意識してほしいのは次のようなことです。

ヘッダー・フッター・共通の余白やフォント設定は layout.tsx に集める。
各ページは「そのページ固有のコンテンツ」だけに集中する。
ナビゲーションやコピーライトを変更したくなったら layout.tsx を変えるだけで全ページに反映される。

これができると、

ページが増えてもレイアウトをまとめて管理できる
どのページも同じ「顔つき」になり、サービスとして統一感が出る
後からデザインを変えたくなっても修正箇所が最小限で済む

という状態になります。

もし余力があれば、次のような工夫も試してみると良いです。

ヘッダーにサイトロゴ風のテキストやアイコンを追加する
フッターに簡単なリンク(プライバシーポリシー等のダミー)を置いてみる
main の幅を maxWidth で制限して、中央寄せレイアウトにしてみる

そうすると、「Next.js アプリ」というより「ちゃんとした Web サービスの画面」にグッと近づいていきます。

タイトルとURLをコピーしました