4
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?

Reactのルーティング(React Router)を最近覚えた

4
Last updated at Posted at 2026-06-29

異業種からIT企業に転職して半年以上の初心者です:beginner:

現場配属されて早3か月が経過しました!はやい!
毎月何かをアウトプットしたいという思いから4月より投稿を継続していますが、今月は、新規画面を実装した時に初遭遇したルーティング(React Router)について備忘録としてまとめたいと思います:angel_tone2:

React Routerとは

SPA(シングルページアプリケーション)において、画面遷移を行うときは一度HTMLを読み込んだ後、部品(Component)を差し替えて画面遷移をしているかのように振舞います。
この画面遷移をルーティングといい、ReactではReact Routerを用いて実現させます。

感覚としては経路を指定してあげるイメージです↓

Aさん:この商品興味があるから画像見たけどやっぱ違ったとき
リンクをクリック→ページB→ページC→ページA

image.png

実装編

仕事現場ではReactのバージョンがv5以下、私が自身で試した作業環境はv6です。
バージョンの違いによって書き方が異なるようだったので、2通りの書き方を備忘録として残しておきます。

ディレクトリ構成

src/
├── pages/
│   ├── Top.tsx       (トップページ)
│   ├── Mypage.tsx    (マイページ)
│   └── Blog.tsx      (ブログページ)
└── App.tsx           (ルーティング定義)

v5以下

App.tsx
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Top from './pages/top';
import Mypage from './pages/mypage';

export default function App() {
  return (
    <Router>
      <Switch>
      {/* exact は完全一致。つけないと、'/' がすべてに前方一致してしまうため必須。 */}
        <Route exact path="/" component={Top} />
     {/* /mypage/blog も含めるため、ここでは exact はつけず、部分一致させる。*/}
        <Route path="/mypage" component={MyPage} />
      </Switch>
    </Router>
  );
}
Top.tsx
]import React from 'react';
import { Link } from 'react-router-dom';

export default function Top() {
  return (
    <div>
      <h1>Top Page</h1>
      <Link to="/mypage">My Pageへ</Link>
    </div>
  );
}
MyPage.tsx
import React from 'react';
import { Route, Switch, useRouteMatch, useHistory } from 'react-router-dom';
import Blog from './Blog';

export default function Mypage() {
  const { path, url } = useRouteMatch();
  const history = useHistory(); // 画面遷移のためのhistoryオブジェクトを取得

  // 各ボタンのクリックハンドラー
  const onClickBack = () => {
    history.push('/');
  };

  const onClickBlog = () => {
    history.push(`${url}/blog`);
  };

  return (
    <div>
      <h1>My Page</h1>
      <nav>
        <button onClick={onClickBack}>戻る</button>
        <button onClick={onClickBlog}>ブログを見る</button>
      </nav>
      <hr />
      <Route path={`${path}/blog`} component={Blog} />
    </div>
  );
}
Blog.tsx
import React from 'react';
import { useHistory } from 'react-router-dom';

export default function Blog() {
  const history = useHistory();

  const onClickBack = () => {
    history.goBack();
  };

  return (
    <div>
      <h2>Blog</h2>
      <button onClick={onClickBack}>戻る</button>
    </div>
  );
}

v6

App.tsx
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import { Top } from './pages/Top.tsx';
import { MyPage } from './pages/MyPage.tsx';
import { Blog } from './pages/Blog.tsx';

export const App = () => (
  <BrowserRouter>
    <div>
      <Routes>
        <Route path="/" element={<Top />} />
        <Route path="/mypage" element={<MyPage />} />
        <Route path="/mypage/blog" element={<Blog />} />
      </Routes>
    </div>
  </BrowserRouter>
);
Top.tsx
import { Link } from 'react-router-dom';

export const Top = () => {
  return (
    <div>
      <h1>Top Page</h1>
      <Link to="/mypage">My Pageへ</Link>
    </div>
  );
};

MyPage.tsx
import { useNavigate } from 'react-router-dom';

export const MyPage = () => {
  const navigate = useNavigate();
  const onClickBlog = () => {
    navigate('/mypage/blog');
  };
  const onClickBack = () => {
    navigate(-1);
  };
  return (
    <div>
      <h1>My Page</h1>
      <button onClick={onClickBlog}>Blogを見る</button>
      <button onClick={onClickBack}>戻る</button>
    </div>
  );
};
Blog.tsx
import { useNavigate } from 'react-router-dom';

export const Blog = () => {
  const navigate = useNavigate();

  const onClickBack = () => {
    navigate(-1);
  };
  return (
    <div>
      <h1>Blog</h1>
      <button onClick={onClickBack}>My Pageに戻る</button>
    </div>
  );
};

v5とv6の違い

パスのマッチ順

v5
BrowserRouterの中で<switch>を使用して上から順にパスを判定するため、exactを使用するかを考える必要があります。
上記のv5のApp.tsxを以下のようにexactを付けないで記述すると、Blogページに飛びたいのにMyPageのパスが先にマッチしてしまうので、画面上にMypageとBlogが二重で表示されてしまいます。(これを知らずに少し沼りました。。。)

App.tsx(v5 抜粋:exactなし)
 <Route path="/mypage" component={MyPage} />
 <Route path="/mypage/Blog" component={Blog} />

exactはパスを完全一致で検索するため、つけないと部分一致で検索することになる

v6
v6では<switch>が不要となります!
パスを<Routes>で囲み、必ずパスを完全一致でマッチさせるようになったのでexactを付与する必要もなくなりました。

component属性とelement属性

v5component属性
v6element属性
component属性ではコンポーネントに値を渡すときはrender属性を使用する必要がありますが、element属性ではその必要がなくなるため、より直感的で簡便に記述することができるそうです。

ページ遷移

//v5の場合
const history = useHistory();
history.push('path名');
history.goBack();  //1ページ前に戻る
history.back(-2);  //2ページ前に戻る

//v6の場合
const navigate = useNavigate();
navigate('path名');
navigate(-1);  //1ページ前に戻る

v5useHistory
v6useNavigate
v5ではuseHistoryを使用してページ遷移を行いますが、v6ではuseNavigateを使用することでページ遷移を行います。
引数に整数を入れることで履歴があれば、その分ページを進んだり戻ったりすることができます。

さいごに

今回、現場で初めて触れたReact Routerについて復習する中でバージョン違いによる記述の違いにまでたどり着くことができました。
バージョンの違いについてはまだまだありそうですが、今回触れたのはここまででしたので機会があれば、もう少し踏み込んでみようと思います!
最後まで閲覧いただきありがとうございました。
何かありましたら、ご指摘いただけますと幸いです。

4
5
3

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
4
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?