SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Next.jsの新しい概念を学ぶ

Next.js 13の新機能「App Router」でコンテンツ部分だけを更新する

Next.jsの新しい概念を学ぶ 第2回

  • X ポスト
  • このエントリーをはてなブックマークに追加

 App Routerという仕組みには、Webサイトを快適に制作するためのツールとしての側面があります。その一環として、Nested Routesという機能があり、これを扱うことでWebサイトのページ構造に対して素直な構造を生み出すことができます。今回は、このNested Routesを中心に解説します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

対象読者

  • JavaScriptとWeb開発の基礎に理解がある方
  • Reactを用いたJavaScriptアプリケーション開発の経験者

前提環境

 筆者の検証環境は以下の通りです。

  • macOS Ventura 13.4
  • Node.js 20.6.1/npm 9.8.1
  • React 18.2.0
  • Next.js 13.4.19

Nested Routesでページ内の一部分だけを別のファイルで定義する

 前回はHacker Newsの最新20件を読めるアプリケーションを途中まで作り、メニューが表示できるようになりました。図1のように、idがsidebarになっているメニュー部分と、コンテンツを表示する予定の<main>要素で構成されています。

図1:前回はメニューまでを作った
図1:前回はメニューまでを作った

 メニューを作ったので、次はメニューの項目をクリックしたときに、<main>要素にある本文に記事を表示したいですね。具体的には、/top20/xxxxxxのようなURLへアクセスしたときに、本文が表示されると嬉しいです。

 こういった挙動を作るときに役立つのが、Nested Routes(ネステッドルーツ)と呼ばれる機能です。ルート(ページ)の定義をネスト(入れ子)にすることで、画面遷移の際にページ内の一部分だけを更新することができます。

1つのページのレイアウトを複数のファイルで構成する

 実際の挙動を見たほうが早いので、手を動かしてみましょう。まずは、前回作った/top20/page.jsをリネームして、/top20/layout.jsにします。layout.jsはApp Routerのファイルとフォルダによるルーティングにおける予約されたファイル名のひとつで、レイアウトという機能を実現するためのものです。

 続けて、ファイル内にも少し手を入れます(リスト1)。

[リスト1]app/top20/page.js → app/top20/layout.js
// (省略)
export default async function Top20Layout({ children }) { // (1)
// (省略)
<main>
  {children}{/* (2) */}
</main>
// (省略)

 まずは、(1)の変更です。ファイル名に合わせて、コンポーネント名をTop20PageからTop20Layoutに変更しました。また、propsとしてchildrenを取り出しています。(2)では、そのchildren<main>要素の中で展開しています。図1の時点では<div>本文をここに表示する</div>テキストを仮置きしていた部分ですね。

 このchildrenは、いわゆるプレースホルダーとして機能します。アクセスするURLのパスに応じて、別のファイルで定義したコンポーネントに差し変わります。といっても、どんなパスでも差し替えられるわけではありません。このlayout.jsが設置されたフォルダ以下の階層に配置されたページchildrenに表示されうるものになります。つまり、app/top20/以下に配置したpages.jslayout.jsなどの外側に、リスト1のレイアウトが被さるイメージになります。

 さて、App Routerはpage.jsが置いてあるフォルダパスをアプリケーションのURLパスとして成立させる仕組みなので、page.jsが不在のままにしておくわけにはいきません。改めてapp/top20/page.jsを作りましょう(リスト2)。

[リスト2]app/top20/page.js
import "./_style/article.css"; // (1)

export default function Top20IndexPage() {
  return (
    <article>
      <p>ここに記事が表示されます。</p>
      <p>左のメニューから記事を選択してください。</p>
    </article>
  );
}

 特段複雑なことをしない、静的な表示です。(1)のarticle.cssは、サンプルコードの中にあるので、必要な方はコピーしておいてください。この時点で、appフォルダの中は図2のようになりました。

図2:レイアウトファイルとページファイルを作成する
図2:レイアウトファイルとページファイルを作成する

 では、この状態でhttp://localhost:3000/top20を確認してみましょう(図3)。

図3:Nested Routes
図3:Nested Routes

 childrenを配置した場所に、リスト2で実装したapp/top20/page.jsの内容が表示されました。ルート(≒ページ)の中にルートを表示する仕組みであり、Nested Routesと呼ばれています。

 この状態では、Nested Routesの真価はまだ発揮されていません。前述のとおりapp/top20/layout.jsという外側のレイアウトを司るファイルはapp/top20/フォルダ配下のすべての表示可能なファイルに対して適用されるのです。app/top20/page.jsでも、それ以外のファイルでも、同じようにapp/top20/layout.jsが外側のレイアウトとして表示され続けることに真価があります。つまり、/top20/xxxxxxのようなパスを表示するときにも、サイドメニューを表示させ続けることができるのです。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
パラメータ付きのパスを扱う

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Next.jsの新しい概念を学ぶ連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 中川幸哉(ナカガワユキヤ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/18520 2023/10/24 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング