SHOEISHA iD

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

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

Remixを通じてWebを学ぶ

Remixを触る上できちんと知っておきたい機能「Nested Routes」を解説

Remixを通じてWebを学ぶ 第3回

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

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

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

対象読者

  • Reactの基本を修めている方
  • 通信回線が弱いユーザーにも高速に表示できるサイトを作りたいエンジニア
  • WebブラウザとNode.jsという異なるランタイムをそれぞれキャッチアップするのが辛くなってきたエンジニア

前提環境

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

  • macOS Ventura 13.0.1
  • Node.js 18.12.1
  • NPM 8.19.2
  • Remix 1.9.0

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

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

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

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

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

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

 実際の挙動を見たほうが早いので、手を動かしてみましょう。図1の例では <main> 要素の中に <div> 要素を仮置きしていましたが、これを <Outlet /> という要素に置き換えます(リスト1)。 Outlet"@remix-run/react" のインポート文を追記して呼び出します。

[リスト1]app/routes/top20.jsx
import { useLoaderData, Link, Outlet } from "@remix-run/react";
// 中略
<main>
  <Outlet />
</main>

 この <Outlet /> は、いわゆるプレースホルダーです。アクセスするURLのパスに応じて、別のファイルで定義したコンポーネントに差し変わります。といっても、どんなパスでも差し替えられるわけではありません。 <Outlet /> が設置されたファイルと同名のフォルダ内のファイル<Outlet /> に表示されうるものになります。

 テキストだけだとわかりづらいので、実際に簡単な例から表示してみましょう。図2のように、 app/routes フォルダの直下に、 top20 フォルダを作成し、さらにその下に app/routes/top20/index.jsx を作成します。

図2:既存のファイルと同名のフォルダを作成する
図2:既存のファイルと同名のフォルダを作成する

 一見すると app/routes/top20.jsx と同じページを別の表現で作成しただけに見えますが、Remixでは異なる役割を持っており、どちらも必要なので残しておいてください。

 続いて、 app/routes/top20/index.jsx の中身はリスト2のように実装します。

[リスト2]app/routes/top20/index.jsx
import stylesUrl from '~/style/article.css';

export const links = () => {
  return [{ rel: "stylesheet", href: stylesUrl }];
};

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

 特段複雑なことをしない、静的な表示です。

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

図3:Nested Routes
図3:Nested Routes

 <Outlet /> を配置した場所に、リスト2で実装した app/routes/top20/index.jsx の内容が表示されました。routeの中にrouteを表示する仕組みということで、Nested Routesと呼ばれています。 app/routes/top20.jsxapp/routes/top20/index.jsx は、どちらか一方だけが実装されている場合は同じパス(/top20)を表現するための同じ役割のファイルです。

 しかし、同時に実装した場合には、 app/routes/top20.jsx が外側のレイアウト部分を担当し、 app/routes/top20/index.jsx がコンテンツ部分を担当するように、役割が変わるのです。

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

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

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

  • X ポスト
  • このエントリーをはてなブックマークに追加
Remixを通じてWebを学ぶ連載記事一覧

もっと読む

この記事の著者

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

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

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング