React Router バージョン6系でDynamic Routingを実装する方法を解説します。
/articles/1
や/articles/2
にアクセスすると1や2のpath部分を動的にできるものです。
※ダイナミックセグメント(dynamic segment)と公式ページでは紹介されています。
今回2パターンを解説します。
- useParamsを使う方法
- loaderを使う方法
モグモグさん
loaderはv6.4から登場した新しい機能で、ユーザー体験の向上にもつながるのでこちらを使うことをオススメします。
- react 18.2.0
- react-router-dom 6.6.1
モグモグさん
本記事ではTypeScriptを使っています。
使っていない方は、tsx
をjsx
、型定義を削除するなど適時置き換えていただけますと幸いです。
ルーティングの基本についてはこちらで解説しています。
【React Router v6系】React Routerを導入し基本的なページ遷移を行う方法を解説
Dynamic Routing定義
まずはルーティングを作成しDynamic Routingを定義していきます。
例なので出来るだけシンプルな形で定義していきます。
ルーティング定義
path: ":slug"
の箇所が重要です。
これでDynamic Routingになります。
Articleページで、slugというパラメータが取得できます。
モグモグさん
例えば、slugをidにすればidというパラメータが取得できます。
import React from "react";
import { createBrowserRouter } from "react-router-dom";
import { ErrorPage } from "./screens/Error";
import { Layout } from "./screens/Layout";
import { Article } from "./screens/Article";
export const router = createBrowserRouter([
{
path: "/articles",
element: <Layout />,
errorElement: <ErrorPage />,
children: [{ path: ":slug", element: <Article /> }],
},
]);
ルートファイルでルーティングを定義したファイルを呼び出す
ルーティングを定義したAppRoutesをルートから呼び出します。
モグモグさん
ルートファイルはみなさんの環境に合わせてください!
本記事では、create-react-appを使っているのでsrc/index.tsx
がルートファイルになります。
ルーティングを定義したファイルを作成せず、ルートファイルに直接書いてももちろんOKです。
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import reportWebVitals from "./reportWebVitals";
import { RouterProvider } from "react-router-dom";
import { router } from "./components/AppRoutes";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
useParamsでパラメータを取得
それでは、Articleコンポーネントでslugを取得していきます。
import { FC, useEffect } from "react";
import { useParams } from "react-router-dom";
export const Article: FC = () => {
const { slug } = useParams();
useEffect(() => {
// Do something with slug
}, [slug]);
return (
<div>
<h1>slug</h1>
</div>
);
};
例えば、articles/abc
とすると<h1>
にはabcが表示されます。
あとは取得したパラメータを使ってAPIを叩いたり…のようなことを行うことが多いと思います。
loaderでパラメータを取得
続いて、loaderを使うパターンで取得してみましょう。
ルーティングファイルにloaderを追加
ルートでloaderに関数を渡すとパラメータを取得することができます。
import React from "react";
import { createBrowserRouter, LoaderFunctionArgs } from "react-router-dom";
import { ErrorPage } from "./screens/Error";
import { Layout } from "./screens/Layout";
import { Article } from "./screens/Article";
const articleLoader = async ({ params }: LoaderFunctionArgs) => {
return params.slug;
};
export const router = createBrowserRouter([
{
path: "/articles",
element: <Layout />,
errorElement: <ErrorPage />,
children: [{ path: ":slug", element: <Article />, loader: articleLoader }],
},
]);
Articleページで取得
loaderの関数で返した値は、useLoaderData()
の中に入っていますので動的なパラメータを取得することができます。
import { FC } from "react";
import { useLoaderData } from "react-router-dom";
export const Article: FC = () => {
const slug = useLoaderData();
console.log(slug);
return (
<div>
<h1>{slug}</h1>
</div>
);
};
loaderのメリット
例ではただslugを返していましたが、実際にはloaderの関数の中でAPIを叩くなどの処理を行いそのレスポンスをページに返すという実装をすることが多いです。
loaderは画面の表示前に動くので事前にデータを取得した状態でページを表示することができます。
これがloaderのメリットです。
import React from "react";
import { createBrowserRouter, LoaderFunctionArgs } from "react-router-dom";
import { ErrorPage } from "./screens/Error";
import { Layout } from "./screens/Layout";
import { Article } from "./screens/Article";
const articleLoader = async ({ params }: LoaderFunctionArgs) => {
// 例
return await fetchSomething(params.slug);
};
export const router = createBrowserRouter([
{
path: "/articles",
element: <Layout />,
errorElement: <ErrorPage />,
children: [{ path: ":slug", element: <Article />, loader: articleLoader }],
},
]);
まとめ
React Router バージョン6系でDynamic Routingを実装する方法を解説しました。
loaderを使ってより良いユーザー体験を目指してみてください。