🌟

【React】ルーティング設定

2021/04/18に公開約4,900字

React 初心者です。
React のルーティングについて学習したのでまとめてみました。

基本的なルーティング

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

function App() {
  return (
    <BrowserRouter>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/users">Users</Link>

      <Switch>
        <Route path="/about">
          <h1>About</h1>
        </Route>
        <Route path="/users">
          <h1>Users</h1>
        </Route>
        <Route path="/">
          <h1>Home</h1>
        </Route>
      </Switch>
    </BrowserRouter>
  );
}

ネストしたルーティング

users/page1, users/page2 のようにネストしたルーティングを実現したい時。
<Switch></Switch>の塊を中にもう一つ作成する。
render 関数の中で引数に渡している match は props に含まれているプロパティ。
url の書き間違いを避けるため、match の中の url を取り出している。

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

function App() {
  return (
    <BrowserRouter>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/users">Users</Link>

      <Switch>
        <Route path="/about">
          <h1>About</h1>
        </Route>
        <Route
          path="/users"
          render={({ match: { url } }) => (
            <Switch>
              <Route exact path={url}>
                <h1>User</h1>
                <Link to={`${url}/page1`}>Page1</Link>
                <Link to={`${url}/page2`}>Page2</Link>
              </Route>
              <Route path={`${url}/page1`}>
                <h1>User Page1</h1>
              </Route>
              <Route path={`${url}/page2`}>
                <h1>User Page2</h1>
              </Route>
            </Switch>
          )}
        />
        <Route path="/">
          <h1>Home</h1>
        </Route>
      </Switch>
    </BrowserRouter>
  );
}

Url Parameter

users/1, users/100などのIDのように動的に変わる部分、すなわちUrlパラメータを取得したい時。
useParams を用いることで実現できる。

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

type Id = {
  id: string;
};

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

function App() {
  return (
    <BrowserRouter>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/users">Users</Link>

      <Switch>
        <Route path="/about">
          <h1>About</h1>
        </Route>
        <Route
          path="/users"
          render={({ match: { url } }) => (
            <Switch>
              <Route exact path={url}>
                <Link to={`${url}/100`}>Url Parameter</Link>
              </Route>
              <Route path={`${url}/:id`}>
                <UrlParameter />
              </Route>
            </Switch>
          )}
        />
        <Route path="/">
          <h1>Home</h1>
        </Route>
      </Switch>
    </BrowserRouter>
  );
}

stateを受け渡すページ遷移

Link to の引数にstateを渡し、受け取る側の関数にて、useLocation で受け取れる。
以下の例では、配列arrを受け取り、コンソールに出力している。

const Page1 = () => {
  const { state } = useLocation();
  console.log(state);

  return (
    <div>
      <h1>Page1ページです</h1>
    </div>
  );
};

function App() {
  const arr = ["hoge", "fuga", "piyo"];
  return (
    <BrowserRouter>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/users">Users</Link>

      <Switch>
        <Route path="/about">
          <h1>About</h1>
        </Route>
        <Route
          path="/users"
          render={({ match: { url } }) => (
            <Switch>
              <Route exact path={url}>
                <Link to={{ pathname: `${url}/page1`, state: arr }}>Page1</Link>
              </Route>
              <Route path={`${url}/page1`}>
                <Page1 />
              </Route>
            </Switch>
          )}
        />
        <Route path="/">
          <h1>Home</h1>
        </Route>
      </Switch>
    </BrowserRouter>
  );
}

useHistoryを使ったページ遷移

クリックイベントに限らずページ遷移をしたい場合(JS側で挙動を管理したい場合)。
useHistoryを利用することで実現できる。
以下の例ではUsersページでボタンを押すとHomeページに遷移する。

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

const Users = () => {
  const history = useHistory();

  const onClickBack = () => history.push("/");

  return (
    <div>
      <h1>Usersページです</h1>
      <button onClick={onClickBack}>Homeへ</button>
    </div>
  );
};

function App() {
  return (
    <BrowserRouter>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/users">Users</Link>

      <Switch>
        <Route path="/about">
          <h1>About</h1>
        </Route>
        <Route path="/users">
          <Users />
        </Route>
        <Route path="/">
          <h1>Home</h1>
        </Route>
      </Switch>
    </BrowserRouter>
  );
}

参考

Discussion

ログインするとコメントできます