今回は下のAboutページからネストされたページ遷移を表現していきます。
ネストされたページ遷移の方法
About DetailAとAbout DetailBのコンポーネントの2つを用意しました。
export const AboutDetailA = () => {
return (
<div>
<h1>AboutDetailAです</h1>
</div>
);
};
export const AboutDetailB = () => {
return (
<div>
<h1>AboutDetailBです</h1>
</div>
);
};
Aboutにimport { Link } from “react-router-dom”を追加し、遷移先のリンクを追加します。
import { Link } from "react-router-dom"
export const About = () => {
return (
<div>
<h1>Aboutページです</h1>
<Link to="/about/detailA">DetailA</Link>
<br />
<Link to="/about/detailB">DetailB</Link>
</div>
);
};
最後にルーティング設定を追加します。
import React from "react";
import { BrowserRouter, Link, Switch, Route } from "react-router-dom";
import { Home } from "./components/Home";
import { About } from "./components/About";
import { Contact } from "./components/Contact";
import { AboutDetailA } from "./components/AboutDetailA";
import { AboutDetailB } from "./components/AboutDetailB";
export default function App() {
return (
<BrowserRouter>
<div className="App">
<Link to="/">Home</Link>
<br />
<Link to="/about">About</Link>
<br />
<Link to="/contact">Contact</Link>
</div>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route
path="/about"
render={() => (
<Switch>
<Route exact path="/about">
<About />
</Route>
<Route exact path="/about/detailA">
<AboutDetailA />
</Route>
<Route exact path="/about/detailB">
<AboutDetailB />
</Route>
</Switch>
)}
/>
<Route path="/contact">
<Contact />
</Route>
</Switch>
</BrowserRouter>
);
}
確認するとネストされたページ遷移ができました。
Aboutを複数書くことで煩雑に感じるので、propsで受け取ったURLを使うと下記のように変更することができます。
import React from "react";
import { BrowserRouter, Link, Switch, Route } from "react-router-dom";
import { Home } from "./components/Home";
import { About } from "./components/About";
import { Contact } from "./components/Contact";
import { AboutDetailA } from "./components/AboutDetailA";
import { AboutDetailB } from "./components/AboutDetailB";
export default function App() {
return (
<BrowserRouter>
<div className="App">
<Link to="/">Home</Link>
<br />
<Link to="/about">About</Link>
<br />
<Link to="/contact">Contact</Link>
</div>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route
path="/about"
render={({match : {url} }) => (
<Switch>
<Route exact path={url}>
<About />
</Route>
<Route exact path={`${url}/detailA`}>
<AboutDetailA />
</Route>
<Route exact path={`${url}/detailB`}>
<AboutDetailB />
</Route>
</Switch>
)}
/>
<Route path="/contact">
<Contact />
</Route>
</Switch>
</BrowserRouter>
);
}
ルーティング設定の分割
ここまでルーティングの設定はApp.jsxに書いてきましたが、コードの見通しを良くするためにルーティング設定はルーティングのファイルで分割して管理していきます。
src配下にroutingフォルダを追加してRouter.jsxファイルを作成します。そこにApp.jsxのルーティングの設定を移動させます。
import { Switch, Route } from "react-router-dom";
import { About } from "../About";
import { AboutDetailA } from "../AboutDetailA";
import { AboutDetailB } from "../AboutDetailB";
import { Contact } from "../Contact";
import { Home } from "../Home";
export const Router = () => {
return (
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route
path="/about"
render={({match : {url} }) => (
<Switch>
<Route exact path={url}>
<About />
</Route>
<Route exact path={`${url}/detailA`}>
<AboutDetailA />
</Route>
<Route exact path={`${url}/detailB`}>
<AboutDetailB />
</Route>
</Switch>
)}
/>
<Route path="/contact">
<Contact />
</Route>
</Switch>
)}
import React from "react";
import { BrowserRouter, Link } from "react-router-dom";
import { Router } from "./components/routing/Router";
export default function App() {
return (
<BrowserRouter>
<div className="App">
<Link to="/">Home</Link>
<br />
<Link to="/about">About</Link>
<br />
<Link to="/contact">Contact</Link>
</div>
<Router />
</BrowserRouter>
);
}
確認すると正しく実行されています。
更にページ分割を実行してみる
ルーティングの設定を無事にRouter.jsxファイルにまとめることができました。ここでさらにAboutページのネストされた部分を分割してコードをすっきりさせていきたいと思います。
routingフォルダ配下にAboutRoutes.jsxファイルを作成してオブジェクトとしてルーティング設定を設定していきます。
import { About } from "../About";
import { AboutDetailA } from "../AboutDetailA";
import { AboutDetailB } from "../AboutDetailB";
export const AboutRoutes = [
{
path: "/",
exact: true,
children: <About />
},
{
path: "/detailA",
exact: false,
children: <AboutDetailA />
},
{
path: "/detailB",
exact: false,
children: <AboutDetailB />
}
];
import { Switch, Route } from "react-router-dom";
import { Contact } from "../Contact";
import { Home } from "../Home";
import { AboutRoutes } from "./AboutRoutes";
export const Router = () => {
return (
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route
path="/about"
render={({ match: { url } }) => (
<Switch>
{AboutRoutes.map((route) => (
<Route
key={route.path}
exact={route.exact}
path={`${url}${route.path}`}
>
{route.children}
</Route>
))}
</Switch>
)}
/>
<Route path="/contact">
<Contact />
</Route>
</Switch>
);
};