React RouterとNext.jsのルーティング入門:機能・使い心地を比べてみた

Reactでページ遷移を実装する方法はいくつかありますが、代表的なのが React RouterNext.jsのファイルベースルーティング です。
一見すると「Next.jsのほうが簡単そう」に見えるのですが、実際には用途や開発環境によって向き不向きがあります。

本記事では、React RouterとNext.jsのルーティングを機能面・開発体験の両面から比較。
サンプルコードを交えながら、それぞれの特徴と使いどころをわかりやすく解説します。
読み終えた頃には、自分のプロジェクトに最適なルーティング方法がきっと見つかるはずです。

スポンサーリンク

はじめに

ReactとNext.jsでルーティングはどう違う?

ReactはSPA(シングル・ページ・アプリケーション)の構築を目的とするライブラリのため、そもそもルーティングを前提とした造りにはなっていません。
そのため、React Routerという別のパッケージを入れてあげる必要があります。

Next.jsはReactをさらに拡張した機能を持っているため、実はディレクトリを切るだけでルーティングが完成しちゃったりします。

こう聞くと、Next.jsのほうがいいじゃんと思ってしまいますが、向き不向きもあるようで…。

本記事のゴール

ReactとNext.jsでのルーティングの違いを知ること!

違いを知れば、自分が作りたいアプリケーションを作るにはどちらが適しているのかを判断できるようになります。

それが本記事のゴールです。

本記事では、パッケージのインストール等はnpmで紹介します。

React Routerでのルーティング

まずはReactそのものでのルーティング。

冒頭でお話した、React Routerが登場します。

React Routerとは

もともとSPAの構築を目的としているReactに、別ページへの遷移機能を追加できるパッケージ、という認識でよいかと思います。

SPA(シングル・ページ・アプリケーション)とは?

簡単に言うと、1つのページの中で表示を切り替えていくアプリケーションのことです。

通常のWebサイトなどは、ページ遷移をするとページ全体を読み込みなおしています。
これをMPA(マルチ・ページ・アプリケーション)といいます。
もっと突っ込んだ言い方をすると、遷移のたびに次のページの全体をサーバーからまるっと取ってきているのです。

その反面、SPAの場合は遷移時に表示が切り替わる部分だけをサーバーから読み込みます。そのためSPAを操作している時にページ遷移をすると、ヘッダーやフッター、サイドナビなど共通のコンポーネントはそのままに、コンテンツ部分だけが更新されているような感じに見えます(というか実際そうなんですけど)。

X(旧Twitter)のWeb版なんかがわかりやすい例だと思います。
※ちなみに筆者は私生活ではいまだに「Twitter」と呼び続けています。ここではムリして正式名称で言おうと頑張っています(笑)

インストールと基本的な使い方

React Routerの使い方を見てみましょう。

まずはパッケージをインストールします。
Reactで動かしているプロジェクトを開き、以下をターミナルに打ち込んでEnter。

npm install react-router-dom

パッケージ名は「React Router」なのですが、npm install時の名称は「react-router-dom」となりますので注意。

次に、src/App.jsxに以下を記述して読み込みます。

import { BrowserRouter, Routes, Route, Link } from "react-router-dom";

「BrowserRouter」「Routes」「Route」「Link 」の4つです。

BrowserRouterは、ルーティングをするページを読み込んだ部分全体のラッパーになります。
Routes(複数形)とRoute(単数形)は両方必要ですのでお忘れなく。

4つ目の「Link」が、通常のHTMLでいうaタグの役割をします。

実際の使い方は実装例を見たほうが早い!ということで次行きます。

ページ遷移の実装例(コード付き)

今回はシンプルに、トップページ(src/pages/Home.jsx)とアバウトページ(src/pages/About.jsx)をルーティングしてみましょう。

今回使用するsrcディレクトリ内の構成は以下です(必要なもののみ。他は省略しています)。

src
├── pages
│ ├── About.jsx
│ └── Home.jsx
└── App.jsx

src/pagesの中にページ本体になるファイルが入っていて、src直下にそれらを統括するApp.jsxがいます。

まずはページコンポーネントの中身を簡単に書きましょう。

// src/pages/Home.jsx

export default function Home() {
  return <h1>ホームページ</h1>;
}
// src/pages/About.jsx

export default function About() {
  return <h1>アバウトページ</h1>;
}

次にアプリ全体の親となるApp.jsxを見てみましょう。
こちらには、react-router-domからBrowserRouter, Routes, Route, Linkを読み込んでいるんでしたね。

// src/App.jsx

import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";

export default function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">ホーム</Link> | <Link to="/about">アバウト</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </BrowserRouter>
  );
}

※ルーティングにかかわる記述は少し太字にしてあります。が、だいぶ見づらいですね。。

それぞれの行は以下の役割をしています。

  • 3~5行目 :react-router-domと各ページファイルを読み込む
  • 9・17行目 :BrowserRouterで全体をラップしてあげる
  • 13・16行目:Routes(複数形)でページとなるコンポーネントをラップしてあげる
  • 14・15行目:各ページファイルをRoute(単数形)で指定

Linkタグが、HTMLのaタグに似ていますね。ちょっと比較してみましょうか。

// 通常のHTMLのaタグ
<a href="/">ホーム</a>

// React RouterのLinkタグ
<Link to="/">ホーム</Link>

使い方もほとんど同じで、href=”” が to=”” に変わるイメージです。
あと、LinkのLは必ず大文字にしてください。でないと動かなくなっちゃいます。

さて、React単体すなわちReact Routerでのルーティング設定はこんな感じです。結構大変かも?

Next.jsでのルーティング

次はNext.jsを使ったルーティングを見てみましょう。

ちなみにNext.jsはReactをベースに開発されたフレームワークなので、根本的にはReactです。
さらにそこに、SSR(サーバーサイドレンダリング)やSSG(静的サイトジェネレータ)など様々な機能を追加したものです。

Next.jsのルーティングの特徴

Next.jsでは「ファイルベースルーティング」が採用されています。

これはファイル構造がそのままURL構造になるというもので、ページファイルをsrc/pagesディレクトリに配置するだけで、なんと自動的にルートが生成されるのです。

pagesディレクトリ構造と自動ルーティング

pagesディレクトリ内に作ったファイルは、以下のようにURLとして認識されます。

  • ファイル:pages/index.jsx → URL:”/”
  • ファイル:pages/about.jsx → URL:”/about”

さらに、ファイル名を[]で囲むと、動的ルーティングの設定もできます。
例えば、pages/posts/[id].jsx とすると、/posts/1 や /posts/abc のようにURLの一部を動的に取得して、記事ページなどを表示できます。

Next.jsのルーティングにはさらに種類があります。
上記は従来の「Page Router」という仕組みを利用した方法です。新しいバージョンのNext.jsでは「App Router」というものが導入されており、さらに柔軟なルーティングが可能になっています。

「App Router」ではpagesディレクトリを使わず、appディレクトリ配下にpage.jsxを置く構造になります。index.jsxではなく、必ずpage.jsxという名前を使うのが特徴です。

ページ遷移の実装例(コード付き)

Page Router版とApp Router版の両方を、コード付きの実装例でみてみましょう。

Page Router版

src配下は以下のような構造にしました。
(ルーティングの説明に必要なファイルのみ記載しています)

src
├── pages
│ ├── _app.jsx
│ ├── about.jsx
│ └── index.jsx

_app.jsxは全ページ共通のレイアウトや状態管理を設定するファイル、index.jsxとabout.jsxはページファイルです。

React Routerの場合、ページファイル名は大文字から始めていましたが、Next.jsのルーティングではファイル名がURLパスに影響することがあるため、基本小文字で始めます。

ページファイルの記述は先ほどと同じようにしましょう。

// src/pages/index.jsx

export default function Home() {
  return <h1>ホームページ</h1>;
}
// src/pages/about.jsx

export default function About() {
  return <h1>アバウトページ</h1>;
}

React Routerでのルーティングでは、ここからパッケージの追加インストールや読み込みの記述の追加などを行いました。

Next.jsのPage Routerのルーティングではそれは必要ありません。すでにルーティング可能になっています。ためしに、npm run devでlocalhost:3000を起動し、”/”と”/about”にアクセスしてみてください。

アクセスできましたか?

React Routerの時、Linkタグを用いて各ページを接続しました。それはNext.jsのルーティングでも同じようにLinkタグを使用しますが、ちょっとだけ違いがあります。

index.jsxから、about.jsxにリンクをつないでみましょう。

// src/pages/index.jsx

import Link from "next/link";

export default function Home() {
  return (
    <div>
        <h1>ホームページ</h1>
        <Link href="/about">アバウトページへ</Link>
    </div>
  );
}

今回は、Linkタグを”next/link”から読み込み、そのままreturn内で使用しています。React Routerではto=”” と記述していましたが、Next.jsのルーティングの場合はhref=”” で記述します。こちらのほうが、よりaタグに近い使用感ですね。

App Router版

Next.js 13から導入された、App Router版も見てみます。

今回のディレクトリ構成は以下の通りです。(ルーティングの説明に必要なファイルのみ記載)

src
├── app
│ ├── layout.jsx
│ ├── about
│ │ └── page.jsx
│ └── page.jsx

App Routerでは、pagesディレクトリではなくappディレクトリを使います。
そして、index.jsxではなくpage.jsxというファイルを作ります。

layout.jsxで、同じディレクトリ内にあるページすべての共通のレイアウトを設定します。
上記にはappディレクトリ内にしか入れていませんが、aboutディレクトリ内にlayout.jsxを作ればaboutディレクトリ内の全ページに共通のレイアウトを設定することもできます。

先ほどはページファイル(.jsx)自体の名前を「about」などにしていましたが、App RouterではURLに反映させたい名前のディレクトリを作り、その中に必ずpage.jsxを置きます。

各ページファイルの記述は以下のようにします。

// src/app/page.jsx

import Link from "next/link";

export default function Home() {
  return (
    <div>
      <h1>ホームページ(App Router版)</h1>
      <Link href="/about">アバウトページへ</Link>
    </div>
  );
}
// src/app/about/page.jsx

export default function About() {
  return <h1>アバウトページ(App Router版)</h1>;
}

Page Router同様、トップページからアバウトページに遷移ができます。

React RouterとNext.jsの比較

React RouterとNext.js(さらにPage RouterとApp Router)の説明と実装例を見てきました。

結構違いがありましたね。
違いを以下にまとめてみたいと思います。

機能面の違い

項目React Router(React単体)Next.js
ルーティング方式<BrowserRouter> / <Routes> / <Route> を定義ディレクトリ構造 + page.jsx (またはページ名.jxs)で自動生成
インストールreact-router-dom が必要不要(標準搭載)
動的ルートpath="/user/:id" のように定義[id]/page.jsx のようにファイル名で定義
データ取得フロント側で fetch などを利用SSR/SSG/ISRが標準でサポートされ、サーバー側でもデータ取得可能
ビルド成果物完全SPA静的HTMLやSSRレンダリング結果を生成可能

開発体験の違い

項目React Router(React単体)Next.js
初期セットアップReactインストール後にreact-router-domを追加ルーティング込みの環境が作成される
ルート追加コードに<Route>を追加ファイル/フォルダを追加するだけ
学習コストReact経験者に馴染みやすいが設定が多めファイルベースルーティングは直感的だがApp Routerは特有のルールあり
柔軟性ルートや遷移制御をコードで細かく設定できるファイル構造に沿う設計が基本(規約重視)
ページ間リンク<Link to="/path"><Link href="/path">

ReactとNext.js、どちらを選ぶ?

さて、結局ReactとNext.jsのどちらを選ぶべきなのでしょうか。
ルーティング以外の側面も考える必要があるので、今回の記事趣旨からは少し逸れるかも知れませんが、こちらも付け加えておきたいと思います。

ReactとNext.jsは、ルーティングの他にもいろいろな違いがあります。

ReactはそもそもコンポーネントベースでUIを構築するためのライブラリで、SPA構築が得意。
Next.jsはそのReactをベースに、WebサイトやWebアプリを構築するために拡張された機能を持つフレームワークです。また、Next.jsはパフォーマンス重視の制作も可能です。

ルーティングだけの観点ではNext.jsのほうがラクじゃんと思ってしまいがちかもしれませんが、それぞれの強みを活かせる選出をすべきです。

つまり、

  • UIコンポーネントやSPAを構築する場合、既存プロジェクトに組み込みたい場合はReact
  • SSRやSSGなどを必要とする場合や、大規模なWebサイトやWebアプリを構築する場合はNext.js

というような使い分けができるかと思います。

自分が作りたいものやプロジェクトに合わせて、適したものを選べる力を身に着けたいですね。

まとめ

さて今回はReactとNext.jsを、ルーティングの視点で比べてみました。

ぱっと見ラクそうなのはNext.jsだけど、必ずしもそちらを使用すればよい、ということでもないですね。

実は私もまだまだReactとNext.jsを勉強し始めたばかりで、今回記事を書いたことで自分の知識も深まりました。

今後もいろんなサイトやアプリを作って学習を進めていきます!

参考

今さら聞けないSPA(シングルページアプリケーション)とは #初心者 – Qiita

結局ReactとNext.jsのどちらで開発を進めればいいの? #フロントエンド – Qiita

Next.jsとReactの違いとは?どちらを使うべき?メリットとデメリットから比較・検討 | Muscle Codin

コメント

タイトルとURLをコピーしました