🌀

React: React Router v6 でルーティングする step1

2022/01/28に公開

2022年01月28日 Windows11での情報です。

今回はReactでのルーティングについてです。
ルーティングとはリクエストされたURLに応じて処理を振りわけることです。
Reactでルーティングを実装するには、React Routerライブラリを利用するのがスタンダードなようです。

環境

  • vite: v2.7.2
  • node: v16.13.2
  • react: v17.0.2
  • typescript: v4.4.4
  • react-router-dom: v6.2.1

React Router v6

React Router は現在の最新はv6です。
v5とは書き方が変わったようですので、検索する際はバージョンの確認が必要です。

公式サイト
https://reactrouter.com/

React Router v6 をインストール

まずはReact Routerをインストールします。
vscodeのターミナルで下記のコマンドを実行します。

npm install react-router-dom

※package.jsonを確認すると、2021/01/27時点でv6.2.1がインストールされました。

もっとも基本的なルーティング

まずは最もシンプルなルーティングからです。

SampleHomeコンポネント、SamplePage1コンポーネント、SamplePage2コンポーネントを作成します。

components/SampleHome.tsx
import React from "react";

export const SampleHome:React.VFC =() => {
  return (
    <>
      {/*後で実装*/}
    </>
  );
}
components/SamplePage1.tsx
import React from "react";

export const SamplePage1:React.VFC =() => {
  return <h3>Sample Page 1</h3>
}
components/SamplePage2.tsx
import React from "react";

export const SamplePage2:React.VFC =() => {
  return <h3>Sample Page 2</h3>
}

ルーティングを定義したコンポーネントを作成します。
URLに何も指定しないときは「SampleHome」コンポーネントを表示します。
URLに「page1」を指定したときは「SamplePage1」コンポーネントを表示します。
URLに「page2」を指定したときは「SamplePage2」コンポーネントを表示します。

RouterConfig.tsx
import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { SampleHome } from "./components/SampleHome";
import { SamplePage1 } from "./components/SamplePage1";
import { SamplePage2 } from "./components/SamplePage2";


export const RouterConfig:React.VFC =() => {
  return (
    <>
     <BrowserRouter>
      <Routes>
        <Route index element={<SampleHome />} />
        <Route path="page1" element={<SamplePage1 />} />
        <Route path="page2" element={<SamplePage2 />} />
      </Routes>
    </BrowserRouter>
    </>
  );
}

main.tsxでRouterConfigコンポーネントを読み込みます。
※ビルドツールviteでReactプロジェクトを作成するとmain.tsxが一番最初のコンポーネントになりますが、create-react-appでReactプロジェクトを作成すると、一番最初のコンポーネントはindex.tsxになります。(適当に読み替えてください)

main.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import { RouterConfig } from "./RouterConfig";

ReactDOM.render(
  <React.StrictMode>
   <RouterConfig />
  </React.StrictMode>,
  document.getElementById('root')
)

あとはSampleHomeコンポーネントの「{/後で実装/}」部分に、各コンポーネントを表示するためのリンクを作成します。

components/SampleHome.tsx
import React from "react";
import { Link } from "react-router-dom";

export const SampleHome:React.VFC =() => {
  return (
    <>
      <h1>Sample Home</h1>
      <nav>
        <ul>
          <li><Link to="page1">Sample Page1</Link></li>
          <li><Link to="page2">Sample Page2</Link></li>
        </ul>
      </nav>  
    </>
  );
}

動作を確認してみます。

URLに一致しない場合のルーティング

次はURLに一致しない場合のルーティングです。

URLに一致しない場合に表示するコンポーネントを作成します。

cpmponents/NotFound.tsx
import React from "react";

export const NotFound = () => {
  return (
    <>
      <h1>404</h1>
      <h3>お探しのページは見つかりませんでした。</h3>
    </>
  );
}

ルーティングを定義したRouterConfigコンポーネントに、URLに一致しない場合のルート「path="*"」を定義します。

RouterConfig.tsx
import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { SampleHome } from "./components/SampleHome";
import { SamplePage1 } from "./components/SamplePage1";
import { SamplePage2 } from "./components/SamplePage2";
import { NotFound } from "./components/NotFound";

export const RouterConfig:React.VFC =() => {
  return (
    <>
     <BrowserRouter>
      <Routes>
        <Route index element={<SampleHome />} />
        <Route path="page1" element={<SamplePage1 />} />
        <Route path="page2" element={<SamplePage2 />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
    </>
  );
}

動作を確認してみます。

クエリーパラメータを使用する

次はクエリーパラメータを使用したルーティングです。
page2コンポーネントに対してクエリーパラメータ付きのURLでアクセスできるようにします。

ルーティングを定義したRouterConfigコンポーネントは、先ほどまでと変更はありません。

RouterConfig.tsx
import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { SampleHome } from "./components/SampleHome";
import { SamplePage1 } from "./components/SamplePage1";
import { SamplePage2 } from "./components/SamplePage2";
import { NotFound } from "./components/NotFound";

export const RouterConfig:React.VFC =() => {
  return (
    <>
     <BrowserRouter>
      <Routes>
        <Route index element={<SampleHome />} />
        <Route path="page1" element={<SamplePage1 />} />
        <Route path="page2" element={<SamplePage2 />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
    </>
  );
}

SampleHomeコンポーネントで、Page2へクエリーパラメータ付きのリンクを用意します。
Page2へのリンクは3つ。
1つ目はクエリーパラメータがないpage2へのリンクです。
2つ目はクエリーパラメータを「/page2?query1=value1&query2=value2"」と直接かいているpage2へのリンクです。
3つ目はクエリーパラメータを「createSearchParams関数を」で作成しているpage2へのリンクです。

components/SampleHome.tsx
import React from "react";
import { Link } from "react-router-dom";
import { createSearchParams } from "react-router-dom";

export const SampleHome:React.VFC =() => {

  const params: string = createSearchParams({
    query1: "value3",
    query2: "value4"
  }).toString();


  return (
    <>
      <h1>Sample Home</h1>
      <nav>
        <ul>
          <li><Link to="page1">Sample Page1</Link></li>
          <li><Link to="page2">Sample Page2</Link></li>
          <li><Link to="page2?query1=value1&query2=value2">Sample Page2 With Query1</Link></li>
          <li><Link to={`page2?${params}`}>Sample Page2 With Query2</Link></li>
        </ul>
      </nav>  
    </>
  );
}

SamplePage2コンポーネントは、クエリーパラメーターを取り出して表示するように修正します。
クエリーパラメーターを取り出すには「useSearchParams」フックを使用します。

components/SamplePage2.tsx
import React from "react";
import { useSearchParams } from "react-router-dom";

export const SamplePage2:React.VFC =() => {
  
  const [searchParams] = useSearchParams();

  const query1 = searchParams.get("query1");
  const query2 = searchParams.get("query2");


  return (
    <>
      <p>query1={query1}</p>
      <p>query2={query2}</p>
    </>
  );
}

動作を確認してみます。

コンポーネントにpropsを渡す

次はコンポーネントにpropsを渡すルーティングです。

propsを受け取るSamplePage3コンポーネントを、新しく作成します。

components/SamplePage3.tsx
import React from "react";

type Props = {
  Message: string 
};

export const SamplePage3:React.VFC<Props> = (props) => {
  return <p>{props.Message}</p>
}

RouterConfigにSamplePage3へのルートを定義します。

RouterConfig.tsx
import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { SampleHome } from "./components/SampleHome";
import { SamplePage1 } from "./components/SamplePage1";
import { SamplePage2 } from "./components/SamplePage2";
import { SamplePage3 } from "./components/SamplePage3";
import { NotFound } from "./components/NotFound";

export const RouterConfig:React.VFC =() => {
  return (
    <>
     <BrowserRouter>
      <Routes>
        <Route index element={<SampleHome />} />
        <Route path="page1" element={<SamplePage1 />} />
        <Route path="page2" element={<SamplePage2 />} />
        <Route path="page3_hello" element={<SamplePage3 Message="Hello Router" />} />
        <Route path="page3_hi" element={<SamplePage3 Message="Hi Router"/>} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
    </>
  );
}

SampleHomeコンポーネントにはpage3へのリンクを用意します。

SampleHome
import React from "react";
import { Link } from "react-router-dom";
import { createSearchParams } from "react-router-dom";

export const SampleHome:React.VFC =() => {

  const params: string = createSearchParams({
    query1: "value3",
    query2: "value4"
  }).toString();


  return (
    <>
      <h1>Sample Home</h1>
      <nav>
        <ul>
          <li><Link to="page1">Sample Page1</Link></li>
          <li><Link to="page2">Sample Page2</Link></li>
          <li><Link to="page2?query1=value1&query2=value2">Sample Page2 With Query1</Link></li>
          <li><Link to={`page2?${params}`}>Sample Page2 With Query2</Link></li>
          <li><Link to="page3_hello">Sample Page3 Hello</Link></li>
          <li><Link to="page3_hi">Sample Page3 Hi</Link></li>
        </ul>
      </nav>  
    </>
  );
}

動作を確認してみます。

まとめ

以上、基本的なルーティングについて記事にまとめてみました。
だいぶ記事が長くなったので、いったんここで投稿します。
次回も引き続きルーティングについてまとめていきます。

React: React Router v6 でルーティングする step2

Discussion