【不具合のお知らせ】AndroidとiOSに関する一部記事で画像が読み込めない現象が発生しております。

【React Router v6系】React Routerを導入し基本的なページ遷移を行う方法を解説

React Router バージョン6系を導入しページ遷移を行う方法を解説します。

Reactでページ遷移を行う場合は、React Routerを使用するのが一般的です。

React Routerレポジトリ

バージョン
  • react 18.2.0
  • react-router-dom 6.6.1

モグモグさん

本記事ではTypeScriptを使っています。

使っていない方は、tsxjsxなど適時置き換えていただけますと幸いです。

基本的なルーティング

導入から基本的なルーティング方法を解説していきます。

パッケージを追加

まずはパッケージを追加しましょう。

$ npm install react-router-dom

// yarn
$ yarn add react-router-dom

ページを作成する

例として、TopPage1というページを作成します。

モグモグさん

すでにページを実装している方は不要です。

例のページは極端にシンプルにしています。

ディレクトリやファイル名は任意です。

Topページ作成

import { FC } from "react";

export const Top: FC = () => {
  return (
    <div>
      <h1>Top Page</h1>
    </div>
  );
};

Page1を作成

import { FC } from "react";

export const Page1: FC = () => {
  return (
    <div>
      <h1>Page 1</h1>
    </div>
  );
};

ルーティングを設定・管理するファイルを作成

アプリケーション上の全てのページ遷移の設定・管理を行うファイルを作成します。

import React from "react";
import { createBrowserRouter } from "react-router-dom";
import { Top } from "./screens/Top";
import { Page1 } from "./screens/Page1";

export const router = createBrowserRouter([
  { path: "/", element: <Top /> },
  { path: "page1", element: <Page1 /> },
]);

補足

<BrowerRouter>で囲うという書き方もできますが、createBrowserRouterを使うことが公式では推奨されています。

DOM History APIを使っているのと、v6.4から追加されたData APIを使えるようにするためです。

ルートファイルで呼び出す

ルーティングを定義したAppRoutesをルートから呼び出します

モグモグさん

ルートファイルはみなさんの環境に合わせてください!

本記事では、create-react-appを使っているのでsrc/index.tsxがルートファイルになります。

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();

動作確認

react-router-dom<Link>を使うことでaタグを使ってでのページ遷移が可能になります。

Topページにリンクを追加

import { FC } from "react";
import { Link } from "react-router-dom";

export const Top: FC = () => {
  return (
    <div>
      <h1>Top Page</h1>
      <p>
        <Link to="/page1">Page 1</Link>
      </p>
    </div>
  );
};

Page1にリンクを追加

import { FC } from "react";
import { Link } from "react-router-dom";

export const Page1: FC = () => {
  return (
    <div>
      <h1>Page 1</h1>
      <p>
        <Link to="/">Top</Link>
      </p>
    </div>
  );
};

モグモグさん

これでビルドすると、ページ遷移ができていることが確認できます。

コードで遷移する

先ほどは、<Link>を使ってHTMLで遷移しましたが、JSから遷移させることもできます。

TopページでリンクをonClickに変更

import { FC } from "react";
import { useNavigate } from "react-router-dom";

export const Top: FC = () => {
  const navigate = useNavigate();
  return (
    <div>
      <h1>Top Page</h1>
      <p onClick={() => navigate("page1")}>Page 1</p>
    </div>
  );
};

Page1でリンクをonClickに変更

import { FC } from "react";
import { useNavigate } from "react-router-dom";

export const Page1: FC = () => {
  const navigate = useNavigate();
  return (
    <div>
      <h1>Page 1</h1>
      <p onClick={() => navigate("/")}>Top</p>
    </div>
  );
};

モグモグさん

これでビルドすると、<Link>と同様にページ遷移ができていることが確認できます。

エラーページを追加する

続いては存在しないURLにアクセスした場合や何かしらのエラーが発生した場合のエラーページを実装していきましょう。

エラー用ページ作成

この後実装しますが、errorElementにこのページを渡すとuseRouteErrorにはエラーの情報が入ってくるので404のエラーなのか、500のエラーなのか等が判別できて動的にデータを表示することも可能です。

ここではとりあえずエラーログだけ表示しています。

import { FC } from "react";
import { Link, useRouteError } from "react-router-dom";

export const ErrorPage: FC = () => {
  const error = useRouteError();
  console.log(error);

  return (
    <div>
      <h1>Error!</h1>
      <p>
        <Link to="/">Go back to home.</Link>
      </p>
    </div>
  );
};

errorElementに渡す

import React from "react";
import { createBrowserRouter } from "react-router-dom";
import { Top } from "./screens/Top";
import { Page1 } from "./screens/Page1";
import { ErrorPage } from "./screens/Error";

export const router = createBrowserRouter([
  { path: "/", element: <Top />, errorElement: <ErrorPage /> },
  { path: "page1", element: <Page1 /> },
]);

動作確認

サンプルエラーページ

適当なURLにアクセスすると、こんな感じでエラーページが表示されるようになりました!

今回は存在しないURLなので404エラーの情報がログに出力されていると思いますので確認ください。

共通レイアウトを導入する

次に共通レイアウトを導入していきましょう。

よくあるヘッダーとフッターを共通レイアウトとして中身だけページごとに入れ替えるようにします。

Layoutページを作成

モグモグさん

<Outlet>が非常に重要で親ルートのページに設定すると子ルートのページが呼ばれるというものになります。

設定はこの後説明します。

Outletのドキュメント

import { FC } from "react";
import { Link, Outlet } from "react-router-dom";
import { Box } from "@chakra-ui/react";

export const Layout: FC = () => {
  return (
    <>
      <header>
        <nav>
          <ul>
            <li>
              <Link to="/">Top</Link>
            </li>
            <li>
              <Link to="page1">Page 1</Link>
            </li>
          </ul>
        </nav>
      </header>
      <main>
        <Outlet />
      </main>
      <footer>
        <div>
          <p>Footer</p>
        </div>
      </footer>
    </>
  );
};

ルーティングを修正

  • element: <Layout />: 共通のレイアウトを実装したページを指定。
  • children: <Outlet />で呼ばれる子ルート群。
  • index: true: 親ルートのpathで呼びたい場合に指定。

import React from "react";
import { createBrowserRouter } from "react-router-dom";
import { Top } from "./screens/Top";
import { Page1 } from "./screens/Page1";
import { ErrorPage } from "./screens/Error";
import { Layout } from "./screens/Layout";

export const router = createBrowserRouter([
  {
    path: "/",
    element: <Layout />,
    errorElement: <ErrorPage />,
    children: [
      { index: true, element: <Top /> },
      { path: "page1", element: <Page1 /> },
    ],
  },
]);

動作確認

Layoutページ

トップページにアクセスするとこんな感じで、ヘッダーとフッターのレイアウトの中でTopコンポーネントが呼ばれるようになります。

Page1に関しても同様です。

※本記事には含んでいませんが分かりやすいようにスタイルを少し修正しています。

childrenではなく入れ子(JSX)で定義する

機能上は変化はないですが、ルートを定義する場合にJSXの形で書くことが可能です。

createRoutesFromElementsを使います。

import React from "react";
import {
  createBrowserRouter,
  createRoutesFromElements,
  Route,
} from "react-router-dom";
import { Top } from "./screens/Top";
import { Page1 } from "./screens/Page1";
import { ErrorPage } from "./screens/Error";
import { Layout } from "./screens/Layout";

export const router = createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<Layout />} errorElement={<ErrorPage />}>
      <Route index element={<Top />} />
      <Route path="page1" element={<Page1 />} />
    </Route>
  )
);

モグモグさん

好みの問題なので、個人やチームの方針で決めましょう!

まとめ

React Router バージョン6系を導入しページ遷移を行う方法を解説しました。

解説した内容
  • React Routerの導入方法
  • ルーター定義方法
  • リンクとコードからページ遷移する方法
  • 共通レイアウトを定義する方法

これで基本的な内容は抑えられると思いますが、まだまだ重要で便利な使い方がありますので他の記事で解説していきます。

【React Router v6系】React RouterでDynamic Routingを実装する方法を解説

【React Router v6系】React Routerのloaderの基本を解説

【React Router v6系】React RouterでURLのクエリを取得する方法を解説

【React Router v6系】React Routerのactionの基本を解説

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です