React初心者がReact Routerについて勉強した時のメモです。
コード部分が長くなってしまったので前編後編の2回に分けます。
今回は、
- 基本的なページ遷移
- ネストされたページ遷移
- ルーティング分割
- URLパラメーターの値の受け渡し
です。
事前にreact-router-dom
をインストール。
基本的なページ遷移
import { BrowserRouter, Link, Switch, Route } from "react-router-dom";
import { Home } from "./Home";
import { Page1 } from "./Page1";
import { Page2 } from "./Page2";
export default function App() {
return (
<BrowserRouter>
<div className="App">
<Link to="/">Home</Link>
<br />
<Link to="/page1">Page1</Link>
<br />
<Link to="/page2">Page2</Link>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/page1">
<Page1 />
</Route>
<Route path="/page2">
<Page2 />
</Route>
</Switch>
</div>
</BrowserRouter>
);
}
BrowserRouter
で全体を囲みLink
にパスを書きリンクを生成。
どのパスの時にどのコンポーネントをレンダリングするかは、Switch
で全体を囲み、コンポーネントをRoute
で囲みパスを指定。
exact
をつけることで完全一致のみになる。
exact
がないと/
でレンダリングされるので、Page1
と Page2
はレンダリングされずHome
のみのレンダリングになるので注意。
ネストされたページ遷移
import { Home } from "./Home";
import { Page1 } from "./Page1";
import { Page1DetailA } from "./Page1DetailA";
import { Page1DetailB } from "./Page1DetailB";
import { Page2 } from "./Page2";
export default function App() {
return (
<BrowserRouter>
<div className="App">
<Link to="/">Home</Link>
<br />
<Link to="/page1">Page1</Link>
<br />
<Link to="/page2">Page2</Link>
<Switch>
<Route exact path="/">
<Home />
</Route>
-------------------- 追加 --------------------
<Route
path="/page1"
render={({ match: { url } }) => (
<Switch>
<Route exact path={url}>
<Page1 />
</Route>
<Route path={`${url}/detailA`}>
<Page1DetailA />
</Route>
<Route path={`${url}/detailB`}>
<Page1DetailB />
</Route>
</Switch>
)}
>
</Route>
-------------------- 追加 ----------------------
<Route path="/page2">
<Page2 />
</Route>
</Switch>
</div>
</BrowserRouter>
);
}
import { Link } from "react-router-dom";
export const Page1 = () => {
return (
<div>
<h1>Page1ページです。</h1>
<Link to="/page1/detailA">DetailA</Link>
<br />
<Link to="/page1/detailB">DetailB</Link>
</div>
);
};
page1/detailA``page1/detailB
のようにネストされたページ遷移のルーティングの仕方。
render
はデフォルトでprops
を受け取りprops内のmatch
のurl
を使うことでネストされたルーティング部分はpage1
であることを保証している書き方にできる。
ルート定義の分割
ルーティング部分を別ファイルに切り出す。
import { BrowserRouter, Link } from "react-router-dom";
import { Router } from "./router/Router";
export default function App() {
return (
<BrowserRouter>
<div className="App">
<Link to="/">Home</Link>
<br />
<Link to="/page1">Page1</Link>
<br />
<Link to="/page2">Page2</Link>
<Router />
</div>
</BrowserRouter>
);
}
import { Switch, Route } from "react-router-dom";
import { Home } from "../Home";
import { Page2 } from "../Page2";
import { Page1Route } from "./Page1Route";
export const Router = () => {
return (
<Switch>
<Route exact path="/">
<Home />
</Route>
-----------Page1Detail部分-------------------
<Route
path="/page1"
render={({ match: { url } }) => (
<Switch>
{Page1Route.map((route) => (
<Route
key={route.path}
exact={route.exact}
path={`${url}${route.path}`}
>
{route.children}
</Route>
))}
</Switch>
)}
></Route>
-------------------------------------------
<Route path="/page2">
<Page2 />
</Route>
</Switch>
);
};
Page1Detail部分も別ファイルに切り出す。
import { Page1 } from "../Page1";
import { Page1DetailA } from "../Page1DetailA";
import { Page1DetailB } from "../Page1DetailB";
export const Page1Route = [
{
path: "/",
exact: true,
children: <Page1 />
},
{
path: "/detailA",
exact: false,
children: <Page1DetailA />
},
{
path: "/detailB",
exact: false,
children: <Page1DetailB />
}
];
Page1Route
コンポーネントではpath、exactかどうか、レンダリングされるコンポーネントは何か、が分かるように切り出してRouter
コンポーネントでmap
を使うことで実現できる。
URLパラメーター
URLパラメーターはパスにIDのようなパラメーターを渡す部分。
今回はPage2
にIDを渡すことにする。
Page2
もPage1
同様に別ファイルに切り出す。
import { Switch, Route } from "react-router-dom";
import { Home } from "../Home";
import { Page1Route } from "./Page1Route";
import { Page2Route } from "./Page2Route";
export const Router = () => {
return (
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route
path="/page1"
render={({ match: { url } }) => (
<Switch>
{Page1Route.map((route) => (
<Route
key={route.path}
exact={route.exact}
path={`${url}${route.path}`}
>
{route.children}
</Route>
))}
</Switch>
)}
></Route>
<Route
path="/page2"
render={({ match: { url } }) => (
<Switch>
{Page2Route.map((route) => (
<Route
key={route.path}
exact={route.exact}
path={`${url}${route.path}`}
>
{route.children}
</Route>
))}
</Switch>
)}
></Route>
</Switch>
);
};
import { Page2 } from "../Page2";
import { Urlparameter } from "../UrlParameter";
export const Page2Route = [
{
path: "/",
exact: true,
children: <Page2 />
},
{
path: "/:id",
exact: false,
children: <Urlparameter />
}
];
pathの部分に:パラメータ名
と書くことでパラメーターを受け取ることができる。
今回はIDを受け取るので:id
とする。
import { Link } from "react-router-dom";
export const Page2 = () => {
return (
<div>
<h1>Page2ページです。</h1>
<Link to="/page2/100">URL Parameter</Link>
</div>
);
};
Link
部分に今回渡す値の100を設定しておく。
import { useParams } from "react-router-dom";
export const Urlparameter = () => {
const { id } = useParams();
return (
<div>
<h1>Urlparameterページです。</h1>
<p>パラメーターは {id} です</p>
</div>
);
};
useParams
を使うことでパラメーターの値の受け渡しができる。
参考