React Router v6の学習 Part2


動的ルーティングの設定

動的なルーティングについて今回はまとめる。
今回は"/"から"/1"や"/2"などLinkのデータによってURLが変動する仕組みを考える。

User.ts
const users = [
  {
    id: 1,
    name: "Leanne Graham",
    username: "Bret",
    email: "[email protected]",
    address: {
      street: "Kulas Light",
      suite: "Apt. 556",
      city: "Gwenborough",
      zipcode: "92998-3874",
      geo: {
        lat: "-37.3159",
        lng: "81.1496",
      },
    },
    phone: "1-770-736-8031 x56442",
    website: "hildegard.org",
    company: {
      name: "Romaguera-Crona",
      catchPhrase: "Multi-layered client-server neural-net",
      bs: "harness real-time e-markets",
    },
  },
  {
    id: 2,
    name: "Ervin Howell",
    username: "Antonette",
    email: "[email protected]",
    address: {
      street: "Victor Plains",
      suite: "Suite 879",
      city: "Wisokyburgh",
      zipcode: "90566-7771",
      geo: {
        lat: "-43.9509",
        lng: "-34.4618",
      },
    },
    phone: "010-692-6593 x09125",
    website: "anastasia.net",
    company: {
      name: "Deckow-Crist",
      catchPhrase: "Proactive didactic contingency",
      bs: "synergize scalable supply-chains",
    },
  },
  {
    id: 3,
    name: "Clementine Bauch",
    username: "Samantha",
    email: "[email protected]",
    address: {
      street: "Douglas Extension",
      suite: "Suite 847",
      city: "McKenziehaven",
      zipcode: "59590-4157",
      geo: {
        lat: "-68.6102",
        lng: "-47.0653",
      },
    },
    phone: "1-463-123-4447",
    website: "ramiro.info",
    company: {
      name: "Romaguera-Jacobson",
      catchPhrase: "Face to face bifurcated interface",
      bs: "e-enable strategic applications",
    },
  },
];

export const getUsers = () => {
  return users;
};

サンプルとして、3つのユーザー情報の入った配列を使用していきたい。
Page1コンポーネントの中でルーティングすることを想定しているので、

Page1.tsx
import React, { VFC } from "react";
import { Link, Outlet, Route, Routes } from "react-router-dom";
import { getUsers } from "./User";

type PROPS = {
  subtitle: string;
};
export const Page1: VFC<PROPS> = (props) => {
  const users = getUsers();
  return (
    <div>
      <h1>Page1です。</h1>
      <p>{props.subtitle}</p>
      <Outlet />
      <nav
        style={{
          borderRight: "solid 1px",
          padding: "1rem",
        }}
      >
        {users.map((user) => (
          <Link
            style={{ display: "block", margin: "1rem 0" }}
            to={`/${user.id}`}
            key={user.id}
          >
            {user.name}
          </Link>
        ))}
      </nav>
    </div>
  );
};

このようにユーザーの名前をリンクとして、mapで順番に出力しておく。
toには{/${user.id}}を設定しておく。ここをuser.nameにすれば、/nameということも可能になる。

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

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Page1 subtitle="Hello" />}>
          <Route path=":userId" element={<SingleUser />} />
        </Route>
        <Route path="/page2" element={<Page2 />} />
        <Route path="/page3" element={<Page3 />}>
          <Route path="page4" element={<Page4 />} />
        </Route>
        <Route path="*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

動的なルーティングの場合、path=":userId"のように、: と任意の名前をつけたものを設定しておく。
userIdはどこで使用できるかというとSingleUserコンポーネントの中で、useParamsを使用することで、
そのページの”/”の後の部分をとってくることができる。(”/1”の場合は1といったように)

SingleUser.tsx
import React, { VFC } from "react";
import { useParams } from "react-router-dom";

export const SingleUser = () => {
  const { userId } = useParams();
  return (
    <div>
      <h1>{userId}</h1>
    </div>
  );
};

このuserIdを活用して、APIなどを叩くのに有効である。

useNavigateについて

軽くまとめると、

const navigate = useNavigate();
navigate('page2')

このような形で、onClickなどと組み合わせて、処理を行なった後にページを移動するのに適している。
useNavigateについては実際に使うタイミングが来たら、もう少ししっかりとまとめたいと思う。