8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

犯人はこいつです

image.png

前提(主なパッケージ)

  "dependencies": {
    "@emotion/styled": "^11.14.1",
    "react": "^19.2.0",
    "react-dom": "^19.2.0",
    "react-router": "^7.9.6"
    "@mui/icons-material": "7.2.0",
  }

はじめに

新たな画面を作成するにあたり、新たなルーティング (URL・ビューの対応付け) を作成する必要が出てきました。

以下のような構成を仮定しましょう。

├── /  「/」
├── /already-exist-routing 「/already-exist-routing」
|
|   // 以下を新規作成
└── /new-routing    「/new-routing」
    └── /hello    「/new-routing/hello」
    └── /about    「/new-routing/about」

本題

ルーティングの定義

先述の/new-routing/*のルーティングをreact-router(<Routes /><Route />)で作成する場合、以下のようなルーティング定義が必要です。

ディレクトリ構成(抜粋)
./src/
├── layout
│   ├── Layout.tsx
│   └── parts
│       ├── Footer.tsx
│       ├── Header.tsx
│       └── Main.tsx
├── pages
│   ├── already-exist-routing.tsx
│   ├── index.tsx
│   ├── new-routing
│   │   ├── about.tsx
│   │   └── hello.tsx
│   └── new-routing.tsx
├── router
|    └── Router.tsx
└── main.tsx

ルーティングは/router/Router.tsxにて定義しています。

Router.tsx
import { type FC } from "react";
import { Route, Routes } from "react-router";
import { Index } from "../pages/index";
import { AlreadyExistRouting } from "../pages/already-exist-routing";
import { NewRouting } from "../pages/new-routing";
import { NewRoutingHello } from "../pages/new-routing/hello";
import { NewRoutingAbout } from "../pages/new-routing/about";

// ルーティング用の定数を定義し、`Array.map`で展開するとよりきれいでしょう。
export const Router: FC = () => (
  <Routes>
    <Route element={<Index />} path="/" />
    <Route element={<AlreadyExistRouting />} path="/already-exist-routing" />
    {/* 「/new-routing」配下のネストしたルーティングを定義 */}
    <Route element={<NewRouting />} path="/new-routing">
      <Route element={<NewRoutingHello />} path="/new-routing/hello" />
      <Route element={<NewRoutingAbout />} path="/new-routing/about" />
    </Route>
  </Routes>
);

以下の記載により、ネストしたルーティングを定義しています。

Router.tsx
    {/* 「/new-routing」配下のネストしたルーティングを定義 */}
    <Route element={<NewRouting />} path="/new-routing">
      <Route element={<NewRoutingHello />} path="/new-routing/hello" />
      <Route element={<NewRoutingAbout />} path="/new-routing/about" />
    </Route>
  • 「/new-routing」にアクセスすると、<NewRouting />が表示
  • 「/new-routing/hello」にアクセスすると、<NewRouting /><NewRoutingHello />が表示
  • 「/new-routing/about」にアクセスすると、<NewRouting /><NewRoutingAbout />が表示
/pages/new-routing/hello.tsx
/pages/new-routing/hello.tsx
import { memo, type FC } from "react";

export const NewRoutingHello: FC = memo(() => (
  <div>
    <h2>「/new-routing/hello」へようこそ!</h2>
  </div>
));
/pages/new-routing/about.tsx
/pages/new-routing/about.tsx
import { memo, type FC } from "react";

export const NewRoutingAbout: FC = memo(() => (
  <div>
    <h2>「/new-routing/about」へようこそ!</h2>
  </div>
));

<Outlet />で対応するビューを表示

そして<NewRouting />にて<Outlet />を用いることで、/new-routing/*の画面を表示できるはずです。

Renders the matching child route of a parent route or nothing if no child route matches.

/pages/new-routing.tsx
import type { FC } from "react";
import { Link } from "react-router";
import { Outlet } from "@mui/icons-material";

export const NewRouting: FC = () => (
  <div>
    <div>
      <h1>「/new-routing」へようこそ!</h1>
    </div>
    <div>
      <nav>
        <ul style={{ listStyle: "none" }}>
          <li>
            <Link to="/new-routing/about">
              「/new-routing/about」
            </Link>
          </li>
          <li>
            <Link to="/new-routing/hello">
              「/new-routing/hello」
            </Link>
          </li>
        </ul>
      </nav>
    </div>
    <div>
      {/* 「/new-routing/*」がここに表示されるはず */}
      <Outlet />
    </div>
  </div>
);

起動してみる

画面を起動した結果がこちら。
image.png

君はだれ...??
image.png

原因

当初、「へーreact-routerってルーティングがうまく定義できていないとアイコン表示するんだ~ すげ~」と思っており、ルーティングの設定周りをデバッグし始めました。
が、おかしいところは見当たらず...
1hほど浪費してしまいました...

...おや、<Outlet />の様子が...

/pages/new-routing.tsx
import { Outlet } from "@mui/icons-material";

はい、<Outlet />react-routerからではなく、様々なアイコン画像を提供してくれるパッケージである@mui/icons-materialからimportされていました...
ということで、import元をreact-routerに修正すると...

/pages/new-routing.tsx
import { Link, Outlet } from "react-router";

image.png

はい、正しく/new-routing/helloのビューである<NewRoutingHello />を表示できました。

あとがき

皆さんもこの顔にはご注意を!
image.png

8
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?