SHOEISHA iD

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

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

Remixを通じてWebを学ぶ

React Routerを元に誕生した「Remix」──ルーティングに関するAPIを解説!

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

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

Remixでルートを定義する

 本連載の中でも時折解説してきましたが、Remixは app/routes/ フォルダの中に配置した、ファイルやフォルダの名前でURLのパスを決定する仕組みを備えています。この仕組みは、公式ドキュメントの中では "File System Route Convention" という言葉で言及されています。省略されて、単に "file convention" と呼ばれることもありますが、大意としては「ファイルシステムを活用したルート定義規約」といったところです。

 それでは、ルート定義のルールを一つずつ確認していきましょう。

HTMLのベースを定義する

 さて、app/routes/ の扱い方の話を始める前段として、Web標準の世界とRemixのルーティングがどう繋がるのかをお話ししておきましょう。といっても複雑な話ではありません。ブラウザに表示するページというのは <html> 要素を最上位に持つDOMツリーを持たないといけませんよね、という至極当たり前の話です。

 Remixで <html> 要素を定義しているのは、app/root.jsx です。このファイルには、Remixを用いて表示するすべてのページをHTML文書として成立させるためのベースとしての役割があります。

 では、実際のファイルの中を見てみましょう(リスト1)。

[リスト1]app/root.jsx
import { cssBundleHref } from "@remix-run/css-bundle";
import {
  Links,
  LiveReload,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
} from "@remix-run/react";

export const links = () => [
  ...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []),
];

export default function App() {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />{/ (2) /}
        <Links />{/ (1) /}
      </head>
      <body>
        <Outlet />{/ (6) /}
        <ScrollRestoration />{/ (5) /}
        <Scripts />{/ (3) /}
        <LiveReload />{/ (4) /}
      </body>
    </html>
  );
}

 眺めてみると、<html><head><body> といった見慣れた要素が記載されています。これらの要素は、基本的にそのままDOMツリーへと描画されます。また、サーバーサイドレンダリングでHTMLファイルを生成するタイミングがあれば、そのベースとしても使われます。

 (1)の <Links />、(2)の <Meta />、(3)の <Scripts /> は、各種設定情報を配置するためのプレースホルダーです。このrootのコンポーネントを元に各ページが描画されるタイミングで、そのページにとって適切な内容の <link><meta><script> といった具体的なDOM要素に置き換わります。

 (4)の <LiveReload /> は開発用の便利ツールです。npm run dev で開発サーバーを立ち上げている間、ソースコードの変更を検知して、ブラウザに表示中のアプリケーションを自動で更新するための手助けをしてくれます。

 (5)の <ScrollRestoration /> は便利ライブラリで、各ページのスクロール位置を保存して、画面を進んだり戻ったりしても、元のスクロール位置で表示してくれます。これが標準で搭載されているのは、Remixの密かな良いところです。

 最後に、(6)の <Outlet /> は、ルーティングを表現するためのプレースホルダーです。app/routes/ に配置したルートファイルの内容は、このコンポーネントの場所に描画されます。初期表示が終わって、シングルページアプリケーションとして画面遷移を始めると、<Outlet /> の中身だけが切り替わっていくイメージです。本記事の大半の話題は、結果的に <Outlet /> の中身をどう切り替えていくか、という話題に終着します。

 ちなみに、app/root.jsx は後述するNested Routes機能を用いて作られたレイアウトの一種であり、その機能の一環として <Outlet /> を使うことができています。ここでは詳しく説明しませんが、後ほどまた言及します。

[コラム]ルートとルート

 Remixの解説には、app/root.jsx のルート(root)と app/routes/ 内に配置するルート(route)という2つの「ルート」が登場します。日本語でカタカナ表記する際には、どちらも同じ「ルート」と記載し、発音にも特に違いを設けないので、少し紛らわしいですね。

 app/root.jsx の "root" はDOMツリーやURLのパスの大元である「根」を表しており、app/routes/ 内に配置するコンポーネントを表す "route" はWebサイト内の「経路」を表しています。解説の中で言及する「ルート」は大半が "route" のことになりますが、本記事のようにどちらも扱う場合には、可能な限り "root" と "route" のどちらなのかを併記し、わかりやすくしておきます。

基本のルート

 それでは、ルート(route)を作成するための基本から解説していきましょう。Remixでは、app/routes/ フォルダの直下にReactコンポーネントのファイルを置くと、ルートとして認識されます。このファイルは、何らかのReactコンポーネントを export default で外部に公開している必要があります。

 例えば app/routes/top20.jsx のようなファイルを置いたときはどうなるでしょうか(図1)。

図1:ファイル名がパスになる
図1:ファイル名がパスになる

 http://localhost:3000/top20 というURLでアクセスできていますね。まずは、これがすべての基本です。

 さて、ファイル名がURLのパスになるとなると、困ったことが出てきます。 http://localhost:3000/ のようなルートパス(root path)を表現した場合にはどうすればよいのでしょうか。まさか空文字に拡張子を付けたファイル名を作るわけにもいきません。

 実は、ルートパスを表現するための特殊なファイル名として、_index.jsx という名前が用意されています(図2)。

図2:ルートパスは_indexで定義する
図2:ルートパスは_indexで定義する

 app/route/_index.jsx に定義されたコンポーネントが、http://localhost:3000/ で表示できましたね。

ルートに付随する情報

 前回までの解説で、ルート(route)として定義したファイルに loaderaction という名前の関数を配置してエクスポートしておくことで、通信機能を利用できることがわかっています。実は、それ以外にも、図2で写り込んでいる meta 関数のように、ルートのファイル内に配置することで特別な役割を担う関数やコンポーネントがあります。今回は詳しく解説しませんが、概要は表1の通りです。

表1:ルート(route)のファイルに定義できる追加機能
名称 種別 概要
action 関数 フォームからのsubmitリクエストを受け付ける関数
ErrorBoundary コンポーネント コンポーネント内で起きたエラーをハンドリングしてエラー表示を出すためのコンポーネント
handle オブジェクト パンくずリストに載せたい自ページの情報を登録する
headers 関数 HTTPヘッダーを定義してCache-Controlなどを制御する
links 関数 <link>要素を定義してCSSなどを制御する
loader 関数 データフェッチのための関数
meta 関数 <title> 要素や <meta> 要素を定義する
shouldRevalidate 関数 どのようなイベントが発生したときにloaderを再実行するのかを定義する

 これまでの例の中で見かけたものもありますね。links 関数は リスト1で app/root.jsx に記載されていましたし、図2には meta 関数が写り込んでいました。

 Remixはページを表示するタイミングで、これらの関数やオブジェクトに定義された情報を集計し、app/root.jsx に記載されていた <Links /><Meta /> といったコンポーネントの内部実装として <link> 要素や <meta> 要素を埋め込んでいくことになります。

次のページ
複雑なルートを定義する

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

  • 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/18573 2023/11/16 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング