hacca8

react-router-domでルーティング

Next.jsなどルーティングも行ってくれるフレームワークを触っているとreact-router-domの使い方を忘れてしまうのでまとめます。
v5からかなり使い方が変わった、v6での利用について。

  • パッケージ
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.4.2",

サンプルに作成したApp.jsを確認します。

App.js

import { BrowserRouter, Route, Routes, Link, Outlet, useParams } from 'react-router-dom'

const Top = () => (
  <>
    <h2>Top</h2>
  </>
)
const About = () => (
  <>
    <h2>About</h2>
  </>
)
const Posts = () => (
  <>
    <h2>Posts</h2>
    <Outlet />
  </>
)
const Post = () => (
  <>
    <h3>PostID: {useParams().id}</h3>
  </>
)

const App = () => (
  <BrowserRouter>
    <h1>Router Test</h1>
    <nav>
      <ul>
        <li><Link to='/'>top</Link></li>
        <li><Link to='/about'>about</Link></li>
        <li><Link to='/posts'>posts</Link>
          <ul>
            <li><Link to='/posts/001'>001</Link></li>
          </ul>
        </li>
      </ul>
    </nav>
    <main>
      <Routes>
        <Route path="/" element={<Top />} />
        <Route path="/about" element={<About />} />
        <Route path="/posts" element={<Posts />}>
          <Route path=":id" element={<Post />} />
        </Route>
        <Route path="*" element={<><h2>404 Not Found</h2></>} />
      </Routes>
    </main>
  </BrowserRouter>
)

export default App

react-router-domの有効化

ルーティングを設定するコードをBrowserRouterで囲みます。

<BrowserRouter>
 〜
</BrowserRouter>

BrowserRouterの外にルーティングを記述すると動作しなくなります。
今回はサンプルのためApp.jsに記述していますが、別コンポーネントに分けても問題ありません。

リンク設置 <Link>

リンクはLinkタグで指定します。aタグによる遷移はリンク先のページ全体を読み込みますが、Linkタグの場合はRoutes内のみを更新するようになりますので、基本的にはこちらを使用します。
外部リンクなどの場合はaタグで記述します。

ルーティングによる内容の変更 <Routes>

Routesタグの中身をルーティングによって切り替えています。
上記App.jsでいう<Link to='/about'>about</Link>をクリックするとURLが/aboutに変わり、内容が<About />に切り替わるのが確認できます。よくあるWebページでいうメインコンテンツをRoutes内で設定しているイメージです。

<Route path="/posts" element={<Posts />}> 〜 </Route><Route path=":id" element={<Post />} />をネストしています。これはURIの階層でいうところの/posts/idを表し、一段下の階層に配置することを表します。
<Posts />を確認するとh2タグの下に<Outlet />が記述されています。Outletタグを設置することで、ネストしたページの内容をここに出力するという指定になります。
この状態で/post/idにアクセスすると

Posts
PostsID:id

と表示されます。ネストしたページの内容が出力されているのが確認できます。

上記のようにコロンをつけて:idとすると動的にURIを変更できるようになります。
指定している<Post />の中身を確認すると、react-router-domのuseParamsを利用してidを取得し、表示するように設定しています。
/posts/001を開くと

Posts
PostID:001

と表示されます。001ページが返ってきていますので、動的にルーティングされているのが確認できます。
また、ネストの中に<Route index element={<PostsIndex />} />を設置すると、/posts/ディレクトリのindexページを指定できます。

:idfirst-postなどに変えてみると、静的なページとしてfirst-postページがルーティングされます。
この状態で/posts/first-postページにアクセスすると

Posts
PostID:

と表示されます。パスが動的な:idではなくなったため、useParamsでidを取得することができなくなりました。

コロンの後の名称でuseParamsに渡すことができます。例えばパスを:slugとすると、useParams().slugで取得できます。

しかし、エラーページの内容にはなりませんのでページが出力されていることが確認できます。
この状態で/posts/001ページにアクセスするとエラーページの内容になりますので、静的なルーティングに変わっているのが確認できます。

NotFoundページの設定

いわゆる404ページのような設定ですが、to=*と指定することでルーティングが設定されていないページは、このページに遷移するよう設定されます。

その他、動的なページ作成について

以上がreact-router-domの基礎的な使用方法になります。APIを使った具体的な活用例については、こちらの記事でまとめています。

ReactでAPIを使って動的にページを表示する