Home
Blog
Products
Profile
Study
Collatz
© 2024 Oizumi Yuta

ブログサイトの Next.js の使い方を振り返る

2024-09-15

概要

本サイトのフロントエンドは Next.js を用いているが、ほとんど ChatGPT に書いてもらったので私の技術的理解は乏しい。 そこで今回出来上がったサイトを元に Next.js の使い方を学んでいく。

Pages

まずはこちらのドキュメントを読んでいく。

Pages

ページは、特定のルートに固有のユーザーインターフェース(UI)です。ページは、page.js ファイルからコンポーネントをデフォルトでエクスポートすることで定義できます。

本サイトでは

app/pages.js
にホーム画面を描画するコードを記載している。

export default function Page() {
  return (
    <div className={styles.main}>
      <h1 className={styles.title}>ようこそ</h1>
      <Image
        src="/home.jpg"
        alt="ホーム画像"
        className={styles.homeImage}
        width={600}
        height={600}
      />
    ...
  );
}

本サイトのドメイン https://oizumi-yuta.com/ にアクセスすると上記描画が行われる。

app/pages.js
はドメインのルートパスにアクセスしたときに描画するコンポーネントというわけだ。

Layouts

Pages が何かわかったところで次にこちらのドキュメントを読んでいく。

Layouts and Templates

レイアウトは、複数のルート間で共有される UI です。ナビゲーション時、レイアウトは状態を保持し、インタラクティブなままで、再レンダリングされません。レイアウトはネストさせることもできます。

レイアウトを定義するには、layout.js ファイルから React コンポーネントをデフォルトエクスポートします。このコンポーネントは、children というプロパティを受け入れる必要があり、レンダリング時に子レイアウト(存在する場合)またはページがこの children に挿入されます。

つまり Pages とは異なり特定のパスのコンテンツを提供するものではなく、共通するレイアウトを提供したいときに定義するものである。違いを整理しておく。

Pages と Layouts の違い

役割の違い

  • Pages: 特定の URL パスに対応する個別のコンテンツや UI を表示
  • Layouts: 複数のページ間で共通して使用される UI を提供し、ナビゲーション時に再レンダリングされない

レンダリングの違い

  • Pages: ページ間を遷移すると、そのページに対応するコンポーネントがレンダリングされる
  • Layouts: ページ間を遷移してもレイアウトは再レンダリングされず、状態を保持する

共通部分の扱い

  • Pages: ページごとに固有の UI
  • Layouts: 共通の要素(例: ヘッダー、ナビゲーションバー)を持つ、複数ページにわたって使い回す構造

Templates

テンプレートは、レイアウトと同様に、子レイアウトやページをラップします。ただし、テンプレートはルート間で持続し状態を維持するレイアウトとは異なり、ナビゲーション時にそれぞれの子コンポーネントに新しいインスタンスを作成します。つまり、テンプレートを共有するルート間をユーザーが移動すると、子コンポーネントの新しいインスタンスがマウントされ、DOM 要素が再作成され、クライアントコンポーネントの状態は保持されず、エフェクトは再同期されます。

これらの特定の動作が必要な場合、テンプレートの方がレイアウトよりも適した選択肢となります。例えば:

ナビゲーション時に useEffect を再同期させたい場合。 ナビゲーション時に子クライアントコンポーネントの状態をリセットしたい場合。 テンプレートは、template.js ファイルからデフォルトの React コンポーネントとしてエクスポートすることで定義できます。このコンポーネントは children プロパティを受け入れる必要があります。

Layouts と Templates は両方とも、子レイアウトやページをラップするため、共通の UI や構造を提供する目的で使用される。 両者の違いは以下の通り。

LayoutsTemplates
状態の保持ページ間を移動しても再レンダリングされず、状態が保持されるページ遷移ごとに再レンダリングされ、新しいインスタンスが作成されるため、状態はリセットされる
DOM 要素の再生成ルート間の遷移時に DOM 要素を再生成しないナビゲーションごとに DOM 要素を再生成する
useEffect
の挙動
レイアウト内のコンポーネントは
useEffect
が再実行されないため、エフェクトの再同期はされない
テンプレートでは遷移のたびに新しいインスタンスが作成されるため、
useEffect
も再実行され、エフェクトが再同期される
適用シナリオ状態の保持や高速なページ遷移が求められる場面で使用される。例: ヘッダーやサイドバーなどの永続的な UIページ遷移ごとに状態をリセットしたり、
useEffect
の再実行が必要な場合に適している。例: フォームのリセットや動的なデータの再フェッチ