👻

React Router v6の学習 Part1

2022/03/30に公開

基本の設定

React Routerによるルーティングを行うためには、BrowserRouterを設定する必要がある。
また、BrowserRouterでRoutes、Routeを囲んでルーティングの設定をする。
下記の記述が一番基礎的なルーティングの記述方法になる。

App.tsx
import { Page1 } from "./Page1";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { Page3 } from "./Page3";
import { Page2 } from "./Page2";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route index element={<Page1 />} />
        <Route path="/page2" element={<Page2 />} />
        <Route path="/page3" element={<Page3 />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

v5ではelement={}という書き方で無くて、<Route></Route>でコンポーネントを挟んでもルーティング設定できていたが、v6ではelement={コンポーネント}という書き方でないとうまくいかなかった。
また、上記コードのように、path="/"はindexと記述することもできる。

NotFoundの設定

次はページが存在しない場合の設定をしていく。

App.tsx
import { Page1 } from "./Page1";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { Page3 } from "./Page3";
import { Page2 } from "./Page2";
import { NotFound } from "./NotFound";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route index element={<Page1 />} />
        <Route path="/page2" element={<Page2 />} />
        <Route path="/page3" element={<Page3 />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

pathに"アスタリスク(*)"を設定することで、上記のコードの場合、"/"、"/page2"、"page3"以外はNotFoundの内容が表示されるようになる。

リンクの設定

次はボタンをクリックしたら、画面を遷移できるような設定をしていく。
Linkコンポーネントを使用して、遷移できるようにするが、ここではto="/"という記述をする必要がある。

App.tsx
import { Link } from "react-router-dom";

function App() {
  return (
    <ul>
      <li>
        <Link to="/">Page1へ</Link>
      </li>
      <li>
        <Link to="/page2">Page2へ</Link>
      </li>
      <li>
        <Link to="page3">Page3へ</Link>
      </li>
     </ul>
  );
}

export default App;

このようにLinkコンポーネントをインポートし、to=""を設定するとクリック時にページの移動ができる。
to=""に設定するのは、path=""で設定したものにする。
aタグで画面遷移を行うこともあるが使い分けとしては、aタグは外部サイトなどに飛ぶ際に設定すると良い。

Propsの設定

App.tsx
function App() {
  return (
    <Route index element={<Page1 subtitle="Hello" />} />
  );
}

export default App;
Page1.tsx
import React, { VFC } from "react";

type PROPS = {
  subtitle: string;
};

export const Page1: VFC<PROPS> = (props) => {
  return (
    <div>
      <h1>Page1です。</h1>
      <p>{props.subtitle}</p>
    </div>
  );
};

このようにpropsでデータを受け取り、それを子コンポーネントで表示させることももちろん可能。

ネスト化

/page3/page4といったページに画面遷移したい場合に設定が必要なネスト化。

App.tsx
<Routes>
  <Route index element={<Page1 subtitle="Hello" />} />
  <Route path="/page2" element={<Page2 />} />
  <Route path="/page3" element={<Page3 />}>
    <Route path="page4" element={<Page4 />} />
  </Route>
  <Route path="*" element={<NotFound />} />
 </Routes>

このように記述すると/page3/page4でPage4の内容が表示される。
ネスト化する際の注意点として、子になるもののpathは原則"/"なしで記述する。(今回の場合はpath="page4"のように)
しかし、これで/page3/page4に遷移すると何も表示されない。

Page3.tsx
import React from "react";
import { Outlet } from "react-router-dom";

export const Page3 = () => {
  return (
    <div>
      <h1>Page3です。</h1>
      <Outlet />
    </div>
  );
};

親のpage3のコンポーネントで<Outlet/>を記述すると、/page3/page4にアクセスした際に、Page4の内容も表示される。
しかし、ここでもまた問題があり、こうする場合はPage3の内容+Page4の内容が表示されてしまう。

App.tsx
<Routes>
  <Route index element={<Page1 subtitle="Hello" />} />
  <Route path="/page2" element={<Page2 />} />
  <Route path="/page3" element={<Page3 />} />
   <Route path="/page3/page4" element={<Page4 />} />
  <Route path="*" element={<NotFound />} />
 </Routes>

それを避けるためには、入れ子にせず対応する必要があるかもしれない。(ここの対処法はもう少し学ぶ必要がある。)

基礎中の基礎をまとめただけだが、自分の頭の中で整理ができたのでよかった。
とりあえず、Part1はこのぐらいにしておきたいと思う。

Discussion