【React】ネストされたページ遷移の方法について学んでいく

React

今回は下のAboutページからネストされたページ遷移を表現していきます。

ネストされたページ遷移の方法

About DetailAとAbout DetailBのコンポーネントの2つを用意しました。

export const AboutDetailA = () => {
  return (
    <div>
      <h1>AboutDetailAです</h1>
    </div>
  );
};
export const AboutDetailB = () => {
  return (
    <div>
      <h1>AboutDetailBです</h1>
    </div>
  );
};

Aboutにimport { Link } from “react-router-dom”を追加し、遷移先のリンクを追加します。

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

export const About = () => {
  return (
    <div>
      <h1>Aboutページです</h1>
      <Link to="/about/detailA">DetailA</Link>
      <br />
      <Link to="/about/detailB">DetailB</Link>
    </div>
  );
};

最後にルーティング設定を追加します。

import React from "react";
import { BrowserRouter, Link, Switch, Route } from "react-router-dom";
import { Home } from "./components/Home";
import { About } from "./components/About";
import { Contact } from "./components/Contact";
import { AboutDetailA } from "./components/AboutDetailA";
import { AboutDetailB } from "./components/AboutDetailB";

export default function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Link to="/">Home</Link>
        <br />
        <Link to="/about">About</Link>
        <br />
        <Link to="/contact">Contact</Link>
      </div>
      <Switch>
        <Route exact path="/">
          <Home />
        </Route>
        <Route
            path="/about"
            render={() => (
              <Switch>
                <Route exact path="/about">
                  <About />
                </Route>
                <Route exact path="/about/detailA">
                  <AboutDetailA />
                </Route>
                <Route exact path="/about/detailB">
                  <AboutDetailB />
                </Route>
              </Switch>
            )}
          />
        <Route path="/contact">
          <Contact />
        </Route>
      </Switch>
    </BrowserRouter>
  );
}

確認するとネストされたページ遷移ができました。

Aboutを複数書くことで煩雑に感じるので、propsで受け取ったURLを使うと下記のように変更することができます。

import React from "react";
import { BrowserRouter, Link, Switch, Route } from "react-router-dom";
import { Home } from "./components/Home";
import { About } from "./components/About";
import { Contact } from "./components/Contact";
import { AboutDetailA } from "./components/AboutDetailA";
import { AboutDetailB } from "./components/AboutDetailB";

export default function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Link to="/">Home</Link>
        <br />
        <Link to="/about">About</Link>
        <br />
        <Link to="/contact">Contact</Link>
      </div>
      <Switch>
        <Route exact path="/">
          <Home />
        </Route>
        <Route
            path="/about"
            render={({match : {url} }) => (
              <Switch>
                <Route exact path={url}>
                  <About />
                </Route>
                <Route exact path={`${url}/detailA`}>
                  <AboutDetailA />
                </Route>
                <Route exact path={`${url}/detailB`}>
                  <AboutDetailB />
                </Route>
              </Switch>
            )}
          />
        <Route path="/contact">
          <Contact />
        </Route>
      </Switch>
    </BrowserRouter>
  );
}

ルーティング設定の分割

ここまでルーティングの設定はApp.jsxに書いてきましたが、コードの見通しを良くするためにルーティング設定はルーティングのファイルで分割して管理していきます。

src配下にroutingフォルダを追加してRouter.jsxファイルを作成します。そこにApp.jsxのルーティングの設定を移動させます。

import { Switch, Route } from "react-router-dom";
import { About } from "../About";
import { AboutDetailA } from "../AboutDetailA";
import { AboutDetailB } from "../AboutDetailB";
import { Contact } from "../Contact";
import { Home } from "../Home";

export const Router = () => {
  return (
  <Switch>
        <Route exact path="/">
          <Home />
        </Route>
        <Route
            path="/about"
            render={({match : {url} }) => (
              <Switch>
                <Route exact path={url}>
                  <About />
                </Route>
                <Route exact path={`${url}/detailA`}>
                  <AboutDetailA />
                </Route>
                <Route exact path={`${url}/detailB`}>
                  <AboutDetailB />
                </Route>
              </Switch>
            )}
          />
        <Route path="/contact">
          <Contact />
        </Route>
      </Switch>

  )}
import React from "react";
import { BrowserRouter, Link } from "react-router-dom";
import { Router } from "./components/routing/Router";

export default function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Link to="/">Home</Link>
        <br />
        <Link to="/about">About</Link>
        <br />
        <Link to="/contact">Contact</Link>
      </div>
      <Router />
    </BrowserRouter>
  );
}

確認すると正しく実行されています。

更にページ分割を実行してみる

ルーティングの設定を無事にRouter.jsxファイルにまとめることができました。ここでさらにAboutページのネストされた部分を分割してコードをすっきりさせていきたいと思います。

routingフォルダ配下にAboutRoutes.jsxファイルを作成してオブジェクトとしてルーティング設定を設定していきます。

import { About } from "../About";
import { AboutDetailA } from "../AboutDetailA";
import { AboutDetailB } from "../AboutDetailB";

export const AboutRoutes = [
  {
    path: "/",
    exact: true,
    children: <About />
  },
  {
    path: "/detailA",
    exact: false,
    children: <AboutDetailA />
  },
  {
    path: "/detailB",
    exact: false,
    children: <AboutDetailB />
  }
];
import { Switch, Route } from "react-router-dom";
import { Contact } from "../Contact";
import { Home } from "../Home";
import { AboutRoutes } from "./AboutRoutes";

export const Router = () => {
  return (
    <Switch>
      <Route exact path="/">
        <Home />
      </Route>
      <Route
        path="/about"
        render={({ match: { url } }) => (
          <Switch>
            {AboutRoutes.map((route) => (
              <Route
                key={route.path}
                exact={route.exact}
                path={`${url}${route.path}`}
              >
                {route.children}
              </Route>
            ))}
          </Switch>
        )}
      />
      <Route path="/contact">
        <Contact />
      </Route>
    </Switch>
  );
};
タイトルとURLをコピーしました