Reactでページ遷移を実装する方法はいくつかありますが、代表的なのが React Router と Next.jsのファイルベースルーティング です。
一見すると「Next.jsのほうが簡単そう」に見えるのですが、実際には用途や開発環境によって向き不向きがあります。
本記事では、React RouterとNext.jsのルーティングを機能面・開発体験の両面から比較。
サンプルコードを交えながら、それぞれの特徴と使いどころをわかりやすく解説します。
読み終えた頃には、自分のプロジェクトに最適なルーティング方法がきっと見つかるはずです。
はじめに
ReactとNext.jsでルーティングはどう違う?
ReactはSPA(シングル・ページ・アプリケーション)の構築を目的とするライブラリのため、そもそもルーティングを前提とした造りにはなっていません。
そのため、React Routerという別のパッケージを入れてあげる必要があります。
Next.jsはReactをさらに拡張した機能を持っているため、実はディレクトリを切るだけでルーティングが完成しちゃったりします。
こう聞くと、Next.jsのほうがいいじゃんと思ってしまいますが、向き不向きもあるようで…。
本記事のゴール
ReactとNext.jsでのルーティングの違いを知ること!
違いを知れば、自分が作りたいアプリケーションを作るにはどちらが適しているのかを判断できるようになります。
それが本記事のゴールです。
React Routerでのルーティング
まずはReactそのものでのルーティング。
冒頭でお話した、React Routerが登場します。
React Routerとは
もともとSPAの構築を目的としているReactに、別ページへの遷移機能を追加できるパッケージ、という認識でよいかと思います。
インストールと基本的な使い方
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
コメント