サイトトップ

Director Flash 書籍 業務内容 プロフィール

HTML5テクニカルノート

Create React App + React Router入門 01: ルーティングを定める


シングルページアプリケーション(SPA)は、ひとつのページでコンテンツを切り替えます。画面が素速く遷移でき、ユーザー体験を高めるための仕組みです。けれどURLが変わらないと、遷移した画面の中のひとつを見ることがむずかしくなります。画面に表示するコンポーネントとURLを結びつけるのが、ルーティングモジュールであるReact Routerの役割です。

01 ルートを定める

Create React AppでつくったReactアプリケーションのひな型に、手を加えてゆきます(ひな型アプリケーションのつくり方については、「Create React App 入門 01: 3×3のマス目をつくる」01「Reactアプリケーションのひな形をつくる」をお読みください)。そのうえで、react-router-domをインストールしてください(「Quick Start」参照)。


npm install react-router-dom

react-router-domに備わるルーターはふたつで、<BrowserRouter><HashRouter>です。URLのもち方と、Webサーバー側の設定に違いがあります。

<BrowserRouter>が用いるパスは、通常のURLです。ただし、サーバーがそのために正しく設定されていなければなりません。それに対して、<HashRouter>はURLに添えるハッシュでルーティングされます(http://example.com/#/your/page)。サーバー側の設定は要りません。今回使うのは、<BrowserRouter>です。

ルーター(<BrowserRouter>)の中に<Route>コンポーネントでpathを定め、ルーティングするコンポーネントはその子として差し込みます。モジュールsrc/App.jsは、つぎのように書き替えてください。URLを指定したパスに書き替えれば、コンポーネントがルーティングされるでしょう(図001)。

src/App.js

import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import './App.css';

function App() {
	return (
		<Router>
			<Route path="/home">
				<Home />
			</Route>
			<Route path="/products">
				<Products />
			</Route>
			<Route path="/settings">
				<Settings />
			</Route>
		</Router>
	);
}
const Home = () => (
	<h2>Home</h2>
);
const Products = () => (
	<h2>Products</h2>
);
const Settings = () => (
	<h2>Settings</h2>
);
export default App;

図001■指定したパスによってコンポーネントがルーティングされる

図001

02 リンクで遷移する

パスを手入力するのでなく、リンクで遷移させましょう。このとき用いるのは、<a>要素ではなく<Link>コンポーネントです。リンク先パスはtoで定めてください。モジュールsrc/App.jsには、つぎのように書き加えます。これでリンクをクリックすれば、コンポーネントが切り替わります。モジュールsrc/App.cssにより、以下のコード001のような簡単なスタイルを割り当てました。

src/App.js

import {

	Link
} from 'react-router-dom';

function App() {
	return (
		<Router>
			<nav>
				<ul>
					<li>
						<Link to="/home">Home</Link>
					</li>
					<li>
						<Link to="/products">Products</Link>
					</li>
					<li>
						<Link to="/settings">Settings</Link>
					</li>
				</ul>
			</nav>

		</Router>
	);
}

図002■リンクでコンポーネントが切り替わる

図002

コード001■アプリケーションのスタイル

src/App.css

body {
	padding-left: 0.5rem;
}
nav ul {
	display: flex;
	padding: 0;
}
nav ul li {
	display: inline;
	margin-right: 0.5rem;
}

03 パスの検索と一致

ホームのページは、ルート(/)に定めるのが普通でしょう。そこで<Link>のパスをつぎのように書き替えます。すると、他のリンクを選んでも、ルートのコンポーネント(Home)もつねに表示されてしまうのです(図002)。これは、ルーティング先の決め方に原因があります。<Route>pathは、与えられたURLと頭の部分が一致していればよく、しかもひとつとは決まっていないのです。たとえば、URLを"/products/something"としてもProductsコンポーネントは表示されます。つまり、ルート(/)のコンポーネントは、必ず表示されるということです。

src/App.js

function App() {
	return (
		<Router>
			<nav>
				<ul>
					<li>
						{/* <Link to="/home">Home</Link> */}
						<Link to="/">Home</Link>
					</li>

				</ul>
			</nav>
			{/* <Route path="/home"> */}
			<Route path="/">
				<Home />
			</Route>

		</Router>
	);
}

図003■pathの指定部分が一致したRouteはすべて表示される

図003

ひとつの対応の仕方は、<Route>に、つぎのようにexactを加えることです。これで、厳密にルートパス(/)でないかぎりHomeコンポーネントは表示されません。その代わり、存在しないたとえば/homeはルーティング先がないことになります。

src/App.js

function App() {
	return (
		<Router>

			{/* <Route path="/"> */}
			<Route exact path="/">
				<Home />
			</Route>

		</Router>
	);
}

04 パスが一致した最初のルートを選ぶ

<Switch>の中に<Route>コンポーネントを定めれば、pathの一致した最初のコンポーネントだけがルーティングされます。複数表示されることはありません。この場合、ルートパス(/)を最後の<Route>pathに置けば、デフォルトのルートになるということです。つぎのコードでは、"/home"などまったく存在しないURLに対してもルート(Home)のコンポーネントが表示されます(図004)。

src/App.js

import {

	Switch,

} from 'react-router-dom';

function App() {
	return (
		<Router>

			<Switch>
				{/* <Route exact path="/">
					<Home />
				</Route> */}

				<Route path="/">
					<Home />
				</Route>
			</Switch>
		</Router>
	);
}

図004■存在しないURLにはルートパスのコンポーネントが表示される

図004

書き上げたアプリケーションモジュールsrc/components/Square.jsの記述全体は、つぎのコード002のとおりです。併せて、CodeSandboxに以下のサンプル001を公開しました。

コード002■アプリケーションのモジュール

src/App.js

import React from 'react';
import {
	BrowserRouter as Router,
	Switch,
	Route,
	Link
} from 'react-router-dom';
import './App.css';

function App() {
	return (
		<Router>
			<nav>
				<ul>
					<li>
						<Link to="/">Home</Link>
					</li>
					<li>
						<Link to="/products">Products</Link>
					</li>
					<li>
						<Link to="/settings">Settings</Link>
					</li>
				</ul>
			</nav>
			<Switch>
				<Route path="/products">
					<Products />
				</Route>
				<Route path="/settings">
					<Settings />
				</Route>
				<Route path="/">
					<Home />
				</Route>
			</Switch>
		</Router>
	);
}
const Home = () => (
	<h2>Home</h2>
);
const Products = () => (
	<h2>Products</h2>
);
const Settings = () => (
	<h2>Settings</h2>
);
export default App;

サンプル001■React Router 01: Basic Routing

05 ルーティングパスを厳密に一致させる

厳密に一致したパスにルーティングさせたい場合について、簡単に解説を加えておきます。<Route>すべてにexactを添えれば済むのはたしかです。けれどそのままでは、一致しない場合にページが空白となってしまいます。それを避けるには、最後の<Route>にエラー(404)ページを置くとよいでしょう。そのときは、つぎのようにpathは与えません。確認のため、以下のサンプル002をCodeSandboxに公開しました。

src/App.js

function App() {
	return (
		<Router>

			<Switch>
				<Route exact path="/products">
					<Products />
				</Route>
				<Route exact path="/settings">
					<Settings />
				</Route>
				<Route exact path="/">
					<Home />
				</Route>
				<Route>
					<NoMatch />
				</Route>
			</Switch>
		</Router>
	);
}

const NoMatch = () => (
	<h2>Not Found</h2>
);

サンプル002■React Router 02: Basic Routing to Exact Paths

Create React App + React Router入門


作成者: 野中文雄
作成日: 2020年05月08日


Copyright © 2001-2020 Fumio Nonaka.  All rights reserved.