アルアカ - Arcadia Academia

Arcadia Academiaは「エンジニアリングを楽しむ」を合言葉に日本のデジタル競争力を高めることをミッションとするテックコミュニティです。

Next.js 入門:Reactとサーバーサイドレンダリングの融合

Featured image of the post

はじめに

Next.js 13から導入されたApp Routerは、従来のPages Routerを置き換える革新的な機能です。ReactのServer Componentsと密接に連携し、クライアントサイドとサーバーサイドの境界を意識せずに、より効率的で柔軟な開発体験を提供します。この記事では、App Routerの基本的な概念や、実際の開発での活用方法について詳しく解説します。また、npx create-next-app@latestを実行した際の対話型プロンプトにも触れ、初心者でもスムーズにプロジェクトを開始できるようにします。

Next.jsのインストールと基本的な使い方

Next.jsのプロジェクトを始めるには、まずNode.jsがインストールされていることを確認しましょう。次に、新しいプロジェクトを作成するために以下のコマンドを実行します。

npx create-next-app@latest

Next.jsのnpx create-next-app@latestを実行すると、対話型のプロンプトが表示され、プロジェクトの設定をカスタマイズできます。英語での質問が表示されるので、以下にその原文とともに解説します。

対話型プロンプトの詳細
  1. Project name (プロジェクト名)

    What is your project named?

    プロジェクトの名前を指定します。任意の名前を入力すると、その名前のディレクトリが作成され、プロジェクトがその中に配置されます。

  2. TypeScriptを使用しますか?

    Would you like to use TypeScript with this project?

    TypeScriptを使用するかどうかを尋ねられます。TypeScriptは型のあるJavaScriptで、エラーを事前に防ぎ、コードのメンテナンス性を向上させます。必要なら「Yes」を選択し、使用しない場合は「No」を選択します。

  3. ESLintをセットアップしますか?

    Would you like to use ESLint with this project?

    コード品質をチェックするためのツールであるESLintをセットアップするかどうかを選択します。コードの一貫性を保ち、バグを未然に防ぐために便利なので、通常は「Yes」を選択するのがおすすめです。

  4. src/ ディレクトリを使用しますか?

    Would you like to use src/ directory?

    デフォルトでは、Next.jsはルートディレクトリにpages/app/フォルダを作成しますが、src/ディレクトリの中にそれらをまとめるかどうかを選べます。大規模なプロジェクトでディレクトリ構造を整理したい場合に役立ちます。

  5. 実験的なApp Router(appディレクトリ)を使用しますか?

    Would you like to use the experimental app directory (recommended)?

    Next.js 13から導入されたApp Routerを使用するかどうかを尋ねられます。App Routerは新しいルーティングシステムで、React Server Componentsとの統合により、パフォーマンスが向上します。新しいプロジェクトでは「Yes」を選択するのがおすすめです。「No」を選択した場合はPage Routerとなります。

  6. Tailwind CSSをインストールしますか?

    Would you like to use Tailwind CSS with this project?

    CSSフレームワークの一つであるTailwind CSSを使うかどうかを選択します。高速なUI開発が可能で、Next.jsと非常に相性が良いので、スタイリングを効率的に行いたい場合は「Yes」を選びます。

  7. src/ ディレクトリに app/ディレクトリを使いますか?

    Would you like to customize the src/app directory structure?

    app/フォルダをsrc/ディレクトリ内に作成して整理するかどうかを選択します。より階層化されたプロジェクト構成を好む場合に選ぶと良いでしょう。

  8. Gitリポジトリを初期化しますか?

    Would you like to initialize a Git repository?

    プロジェクトのバージョン管理のためにGitリポジトリを初期化するかどうかを選べます。Gitを使用する場合は「Yes」を選び、プロジェクトの進行を管理します。

  9. Import aliasを設定しますか?

    Would you like to customize the import alias?

    @components@utilsといったエイリアスを設定するかどうかを選択します。エイリアスを使うと、ファイルパスを短縮でき、特に大規模なプロジェクトでは便利です。

Routerについて

App RouterとPage Routerについての解説です。

App Routerとは?

App Routerは、Next.jsのファイルベースのルーティングを強化した新しい機能です。従来のpages/ディレクトリではなく、app/ディレクトリを使用してアプリケーションのルーティングを管理します。これにより、React Server Componentsの恩恵を受けながら、パフォーマンスや開発効率が大幅に向上します。

主な特徴
  1. React Server Componentsのネイティブサポート

    App Routerでは、React Server Componentsがデフォルトでサポートされています。これにより、サーバーでコンポーネントをレンダリングし、クライアントに最小限のJavaScriptを送信することで、パフォーマンスが最適化されます。

  2. ディレクトリ構造の変更

    pages/ディレクトリではなく、app/ディレクトリ内に各ページやレイアウトを定義します。これにより、レイアウトやページごとの構成がより直感的になり、管理が容易です。

  3. サーバーサイドとクライアントサイドのコンポーネントの統合

    App Routerでは、サーバーサイドで実行されるコンポーネントとクライアントサイドで実行されるコンポーネントを簡単に切り替えられます。use clientというディレクティブを使って、特定のコンポーネントをクライアントサイドで実行するように明示することができます。

App Routerの基本的な使い方
ディレクトリ構造

App Routerを使ったNext.jsプロジェクトは、以下のような構造になります。

/app
  /layout.js    // レイアウトコンポーネント
  /page.js      // メインのページコンポーネント
  /about
    /page.js    // /aboutに対応するページコンポーネント

各ページには必ずpage.jsというファイルを作成します。また、layout.jsはページ間で共通のレイアウトを定義する場所です。

例えば、app/page.jsファイルには以下のようなコードを記述します。

export default function Home() {
  return (
    <main>
      <h1>Welcome to Next.js with App Router!</h1>
    </main>
  );
}

このコードは、/にアクセスしたときに表示されるトップページを定義しています。

動的ルーティング

動的なルーティングもApp Routerで簡単に設定できます。例えば、ユーザーのIDに基づいて動的にページを表示したい場合、以下のようなディレクトリとファイルを作成します。

/app
  /user
    /[id]
      /page.js

[id]というフォルダ名が、動的なルーティングを表します。app/user/[id]/page.jsには次のように記述します。

export default function UserPage({ params }) {
  return (
    <div>
      <h1>User ID: {params.id}</h1>
    </div>
  );
}

これで、/user/123/user/abcといったURLに対応するページが動的に生成されます。

App Routerのメリットとデメリット
メリット
  1. React Server Componentsのネイティブサポート
    • App Routerは、React Server Components (RSC) をネイティブにサポートしており、クライアントサイドとサーバーサイドの境界を自然に扱えます。これにより、サーバー上で処理できる部分はすべてサーバーでレンダリングし、クライアント側に最小限のJavaScriptしか送信しないことで、パフォーマンスが大幅に向上します。
    • 特に、大量のデータを扱うウェブアプリケーションや、ユーザーごとにパーソナライズされたコンテンツを効率よく表示するために有効です。
  2. レイアウト共有とネストされたレイアウトのサポート
    • App Routerでは、ネストされたレイアウトが簡単に実装できます。app/ディレクトリ内にlayout.jsを設定することで、共通のレイアウトを複数のページで使い回すことができ、特定のページやセクションで異なるレイアウトを適用することも可能です。
    • これにより、複雑なUI設計でもコードを分かりやすく保つことができ、再利用可能なレイアウト構造を簡単に管理できます。
  3. 柔軟なデータフェッチング
    • App Routerは、ページ単位で柔軟なデータフェッチングが可能です。getServerSidePropsgetStaticPropsに加え、ページが必要なタイミングでサーバー側やクライアント側でデータを取得できるReact Hooks(例えばuse関数)を利用できます。これにより、ユーザー体験を損なわない効率的なデータ管理が可能です。
  4. 並列フェッチとストリーミングのサポート
    • App Routerは並列フェッチングとストリーミングによるコンテンツの部分的レンダリングをサポートしており、これにより、完全にデータが揃う前にページの一部をユーザーに表示できるため、パフォーマンスが向上します。
    • ユーザーはページの一部を素早く確認できるので、視覚的なフィードバックを早く与えることができ、UXが改善されます。
  5. ディレクトリ構造の一貫性
    • app/ディレクトリを使用することで、レイアウト、ページ、コンポーネントの配置が明確になります。各ページやレイアウトはディレクトリ構造に従って明確に整理され、より体系的な開発が可能です。特に大規模なプロジェクトでは、ページとレイアウトの整理が容易になります。
デメリット
  1. 移行の負担
    • Page RouterからApp Routerへの移行には手間がかかる場合があります。既存のプロジェクトでApp Routerを使おうとすると、ディレクトリ構造やデータフェッチの手法が変更されるため、移行作業に時間がかかることがあります。また、既に運用しているプロジェクトでは、新しい構造に合わせて書き直す必要が生じるため、移行作業が大規模になることもあります。
  2. 学習コストの増加
    • App Routerは多くの新機能を提供しますが、それに伴い新しい概念やAPIの理解が求められます。特に、React Server Componentsやデータフェッチングの新しい仕組み、ストリーミングや並列フェッチングの取り扱いについては、従来の開発手法に慣れた開発者にとっては少しハードルが高く感じるかもしれません。
  3. 複雑なUI設計での負荷
    • App Routerは柔軟性が高い反面、ページの構造が複雑になるとディレクトリやコンポーネントのネストが深くなり、管理が難しくなる場合があります。特に、大規模なアプリケーションで複雑なレイアウトやデータフローを扱う際には、設計を慎重に行わないとコードベースが煩雑化する可能性があります。
  4. App Routerの一部機能がまだ実験的
    • App Routerの多くの機能はまだ比較的新しく、一部が実験的なステータスにあります。そのため、完全に安定していない部分もあり、将来的なAPI変更やバグのリスクが残っている点に注意が必要です。また、React Server Components自体もまだ新しい技術であり、今後の変更に対して柔軟に対応できる体制を整えておく必要があります。
  5. SSRやSSGの複雑化
    • App Routerを利用する場合、サーバーサイドレンダリング(SSR)や静的サイト生成(SSG)に関する処理が複雑になることがあります。特に、React Server Componentsとクライアントサイドのレンダリングのバランスを取る必要があるため、適切な場所で適切な処理を行わないと、パフォーマンスの低下や意図しない動作が発生する可能性があります。

Page Routerとは?

Next.jsのPage Routerは、従来のルーティングシステムで、ファイルベースのルーティングを採用しています。pages/ディレクトリ内の各ファイルが自動的にURLに対応し、開発者が手動でルーティング設定を行う必要がないのが特徴です。Next.js 13で新しいApp Routerが導入されましたが、Page Routerは引き続き利用可能で、特に移行前のプロジェクトや既存の構成に慣れている開発者にとっては重要な選択肢です。

Page Routerの基本的な使い方

Page Routerでは、pages/ディレクトリに置かれたファイルやディレクトリが、そのままURLパスに対応します。例えば、以下のようなディレクトリ構造を持つ場合:

bash
コードをコピーする
/pages
  ├── index.js
  ├── about.js
  └── blog
      └── [id].js

この場合、それぞれのページは次のようなURLでアクセス可能です:

  • /pages/index.jsに対応
  • /aboutpages/about.jsに対応
  • /blog/123pages/blog/[id].jsに対応(動的ルーティング)
例: 基本的なページファイル

pages/index.jsでは、以下のように基本的なReactコンポーネントを定義します。これがルートページとして機能します。

jsx
コードをコピーする
export default function Home() {
  return (
    <div>
      <h1>Welcome to Next.js Page Router</h1>
    </div>
  );
}

このコードをpages/ディレクトリに置くことで、自動的にトップページとして機能し、/にアクセスするとこのコンポーネントがレンダリングされます。

動的ルーティング

Page Routerでは、動的なルーティングもファイルベースで簡単に実現できます。ファイル名に角括弧 [] を使ってパラメータを定義します。例えば、ブログの個別記事ページを動的に生成したい場合、pages/blog/[id].jsというファイルを作成します。

[id]部分が動的に変更され、例えば/blog/123/blog/abcのようなURLに対応します。動的ルーティングは、サーバーサイドで特定のデータを取得する際や、ユーザー固有のページを表示する場合に非常に有用です。

export default function BlogPost({ params }) {
  return (
    <div>
      <h1>Blog Post ID: {params.id}</h1>
    </div>
  );
}

このように、params.idでURLのパラメータにアクセスし、そのデータをページ内で使用できます。

データフェッチング方法

Page Routerでは、サーバーサイドでデータを取得し、ページをレンダリングするための専用メソッドもいくつか提供されています。

  1. getStaticProps

    ビルド時にデータを取得し、静的にページを生成します。ブログや商品カタログのような、更新頻度の低いページに最適です。

    export async function getStaticProps() {
      const res = await fetch('https://api.example.com/data');
      const data = await res.json();
    
      return {
        props: {
          data,
        },
      };
    }
  2. getServerSideProps

    リクエスト時にサーバーサイドでデータを取得し、最新の情報をページに反映させます。動的に変化するデータ(例:ユーザー情報)を扱う場合に便利です。

    export async function getServerSideProps(context) {
      const res = await fetch(`https://api.example.com/data/${context.params.id}`);
      const data = await res.json();
    
      return {
        props: {
          data,
        },
      };
    }
    
  3. getStaticPaths

    動的なページを事前にビルドする際に使用します。例えば、ブログの全ての記事ページをビルド時に生成する際に便利です。

    export async function getStaticPaths() {
      const res = await fetch('https://api.example.com/posts');
      const posts = await res.json();
    
      const paths = posts.map((post) => ({
        params: { id: post.id },
      }));
    
      return {
        paths,
        fallback: false,
      };
    }
ルート間のナビゲーション

Next.jsのPage Routerでは、クライアントサイドのナビゲーションも簡単です。next/linkコンポーネントを使用して、異なるページ間を遷移することができます。これは、ブラウザのページリロードを発生させずに、素早いページ切り替えを実現します。

import Link from 'next/link';

export default function Home() {
  return (
    <div>
      <h1>Welcome to Next.js Page Router</h1>
      <Link href="/about">
        <a>About Us</a>
      </Link>
    </div>
  );
}

このように、<Link>コンポーネントを使ってページ間のリンクを簡単に作成できます。

Page Routerのメリットとデメリット
メリット
  1. シンプルなファイルベースのルーティング

    ファイル名がそのままURLになるため、ルーティング設定が非常に簡単です。大規模な設定ファイルが不要で、初学者でも直感的に扱えます。

  2. SSR(サーバーサイドレンダリング)と静的生成のサポート

    サーバーサイドレンダリングと静的サイト生成の両方をサポートし、SEOやパフォーマンス面で大きなメリットを提供します。

  3. 動的ルーティングの簡便さ

    動的パラメータを用いたルーティングが簡単に実現でき、スケーラブルなアプリケーション開発に最適です。

デメリット
  1. 柔軟性の欠如

    新しいApp Routerに比べ、Page Routerはレイアウトやサーバーサイドとクライアントサイドの分離がやや不便です。特に複雑な構成やカスタムなルーティングが必要な場合は、App Routerのほうが柔軟です。

  2. 将来的なサポート

    Next.jsの進化に伴い、App Routerが主流になる可能性が高く、長期的なプロジェクトではApp Routerへの移行を考慮する必要があります。

まとめ

Next.js 13のApp Routerは、従来のルーティング機能を大幅に強化し、React Server Componentsを活用した効率的なウェブ開発を実現します。npx create-next-app@latestを使えば、プロジェクトを対話的にセットアップでき、初心者から上級者まで柔軟に開発環境を構築可能です。

学習を進める中で不安があれば、プロのメンターに相談してみませんか?
無料カウンセリングを試してみる

あなたを爆速で成長させるメンタリングプログラムはこちらから↓↓

転職ボックス|IT/ゲーム業界の正社員求職者の集客の無料会員登録↓↓