2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[React] React Router 前編

Posted at

React初心者がReact Routerについて勉強した時のメモです。
コード部分が長くなってしまったので前編後編の2回に分けます。
今回は、

  • 基本的なページ遷移
  • ネストされたページ遷移
  • ルーティング分割
  • URLパラメーターの値の受け渡し

です。

事前にreact-router-domをインストール。

基本的なページ遷移

import { BrowserRouter, Link, Switch, Route } from "react-router-dom";

import { Home } from "./Home";
import { Page1 } from "./Page1";
import { Page2 } from "./Page2";

export default function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Link to="/">Home</Link>
        <br />
        <Link to="/page1">Page1</Link>
        <br />
        <Link to="/page2">Page2</Link>

        <Switch>
          <Route exact path="/">
            <Home />
          </Route>
          <Route path="/page1">
            <Page1 />
          </Route>
          <Route path="/page2">
            <Page2 />
          </Route>
        </Switch>
      </div>
    </BrowserRouter>
  );
}

BrowserRouterで全体を囲みLinkにパスを書きリンクを生成。
どのパスの時にどのコンポーネントをレンダリングするかは、Switchで全体を囲み、コンポーネントをRouteで囲みパスを指定。
exactをつけることで完全一致のみになる。
exactがないと/でレンダリングされるので、Page1Page2はレンダリングされずHomeのみのレンダリングになるので注意。

ネストされたページ遷移

App.js
import { Home } from "./Home";
import { Page1 } from "./Page1";
import { Page1DetailA } from "./Page1DetailA";
import { Page1DetailB } from "./Page1DetailB";
import { Page2 } from "./Page2";

export default function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Link to="/">Home</Link>
        <br />
        <Link to="/page1">Page1</Link>
        <br />
        <Link to="/page2">Page2</Link>

        <Switch>
          <Route exact path="/">
            <Home />
          </Route>
      -------------------- 追加 --------------------
          <Route
            path="/page1"
            render={({ match: { url } }) => (
              <Switch>
                <Route exact path={url}>
                  <Page1 />
                </Route>
                <Route path={`${url}/detailA`}>
                  <Page1DetailA />
                </Route>
                <Route path={`${url}/detailB`}>
                  <Page1DetailB />
                </Route>
              </Switch>
            )}
          >
          </Route>
    -------------------- 追加 ----------------------

          <Route path="/page2">
            <Page2 />
          </Route>
        </Switch>
      </div>
    </BrowserRouter>
  );
}
Page1.jsx
import { Link } from "react-router-dom";

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

page1/detailA``page1/detailBのようにネストされたページ遷移のルーティングの仕方。
renderはデフォルトでpropsを受け取りprops内のmatchurlを使うことでネストされたルーティング部分はpage1であることを保証している書き方にできる。

ルート定義の分割

ルーティング部分を別ファイルに切り出す。

App.jsx
import { BrowserRouter, Link } from "react-router-dom";

import { Router } from "./router/Router";

export default function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Link to="/">Home</Link>
        <br />
        <Link to="/page1">Page1</Link>
        <br />
        <Link to="/page2">Page2</Link>
        <Router /> 
      </div>
    </BrowserRouter>
  );
}
Router.jsx
import { Switch, Route } from "react-router-dom";
import { Home } from "../Home";
import { Page2 } from "../Page2";
import { Page1Route } from "./Page1Route";

export const Router = () => {
  return (
    <Switch>
      <Route exact path="/">
        <Home />
      </Route>
  -----------Page1Detail部分-------------------
      <Route
        path="/page1"
        render={({ match: { url } }) => (
          <Switch>
            {Page1Route.map((route) => (
              <Route
                key={route.path}
                exact={route.exact}
                path={`${url}${route.path}`}
              >
                {route.children}
              </Route>
            ))}
          </Switch>
        )}
      ></Route>
  -------------------------------------------
      <Route path="/page2">
        <Page2 />
      </Route>
    </Switch>
  );
};

Page1Detail部分も別ファイルに切り出す。

Page1Route.jsx
import { Page1 } from "../Page1";
import { Page1DetailA } from "../Page1DetailA";
import { Page1DetailB } from "../Page1DetailB";

export const Page1Route = [
  {
    path: "/",
    exact: true,
    children: <Page1 />
  },
  {
    path: "/detailA",
    exact: false,
    children: <Page1DetailA />
  },
  {
    path: "/detailB",
    exact: false,
    children: <Page1DetailB />
  }
];

Page1Routeコンポーネントではpath、exactかどうか、レンダリングされるコンポーネントは何か、が分かるように切り出してRouterコンポーネントでmapを使うことで実現できる。

URLパラメーター

URLパラメーターはパスにIDのようなパラメーターを渡す部分。

今回はPage2にIDを渡すことにする。
Page2Page1同様に別ファイルに切り出す。

Router.jsx
import { Switch, Route } from "react-router-dom";
import { Home } from "../Home";
import { Page1Route } from "./Page1Route";
import { Page2Route } from "./Page2Route";

export const Router = () => {
  return (
    <Switch>
      <Route exact path="/">
        <Home />
      </Route>
      <Route
        path="/page1"
        render={({ match: { url } }) => (
          <Switch>
            {Page1Route.map((route) => (
              <Route
                key={route.path}
                exact={route.exact}
                path={`${url}${route.path}`}
              >
                {route.children}
              </Route>
            ))}
          </Switch>
        )}
      ></Route>
      <Route
        path="/page2"
        render={({ match: { url } }) => (
          <Switch>
            {Page2Route.map((route) => (
              <Route
                key={route.path}
                exact={route.exact}
                path={`${url}${route.path}`}
              >
                {route.children}
              </Route>
            ))}
          </Switch>
        )}
      ></Route>
    </Switch>
  );
};
Page2Route.jsx
import { Page2 } from "../Page2";
import { Urlparameter } from "../UrlParameter";

export const Page2Route = [
  {
    path: "/",
    exact: true,
    children: <Page2 />
  },
  {
    path: "/:id",
    exact: false,
    children: <Urlparameter />
  }
];

pathの部分に:パラメータ名と書くことでパラメーターを受け取ることができる。
今回はIDを受け取るので:idとする。

Page2.jsx
import { Link } from "react-router-dom";

export const Page2 = () => {
  return (
    <div>
      <h1>Page2ページです。</h1>
      <Link to="/page2/100">URL Parameter</Link>
    </div>
  );
};

Link部分に今回渡す値の100を設定しておく。

UrlParameter.jsx
import { useParams } from "react-router-dom";

export const Urlparameter = () => {
  const { id } = useParams();
  return (
    <div>
      <h1>Urlparameterページです。</h1>
      <p>パラメーターは {id} です</p>
    </div>
  );
};

useParamsを使うことでパラメーターの値の受け渡しができる。

参考

2
5
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
2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?