20
18

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-router-dom

Last updated at Posted at 2020-12-09

react-router-dom

Reactで、react-router-domを使ったルーティングを行っていきます。

react-router-domのインストール

terminal
npm i -S react-router-dom

ルーティング

BrowserRouter, Route, Switchのインポート

ルーターになるコンポーネントを作るファイル内でBrowserRouter、Route、Switchをインポートします。

js
import { BrowserRouter, Route, Switch } from "react-router-dom";
要素 内容
BrowserRouter要素 Switch要素をラップする
Switch要素 Route要素をラップする(ラップしたRoute要素のpathが上から1つずつ評価されていく)
Route要素 パスネームとページを紐付けする指定を行う
Route要素のプロパティ 内容
exact pathに指定したパス文字列と、location.pathNameが完全一致した場合のみコンポーネントを返す(exact未指定の場合はfalse)
path パス文字列
component ページに相当するコンポーネントを指定
:key useParams、useRouteMatchで使用

404ページを作る場合のRoute要素

優先順位を一番低くするため、Swith要素内の一番下にpathを書かないで配置します。
(path未指定だと全てのパスネームにマッチしてしまうため)

ルーティングのサンプル

URLによって、ページA~C、404ページを出し分けます。

ルーター

src:App.js
import { BrowserRouter, Route, Switch} from "react-router-dom";
 
//各ページに相当するコンポーネントをインポート
import PageA from './page/PageA';
import PageB from './page/PageB';
import PageC from './page/PageC';
import PageD from './page/PageD';
import Page404 from './page/Page404';


function App() {

  return (

    <BrowserRouter>

      <Switch>

        <Route exact path="/" component={PageA} />
        <Route exact path="/pageb" component={PageB} />
        <Route exact path="/pagec" component={PageC} />
        <Route exact path="/paged" component={PageD} />
        <Route component={Page404} />

      </Switch>

    </BrowserRouter>

  );

}

export default App;

ページA

src/page/PageA.js
import React from 'react'

const PageA = () => {

  return (

      <p>ページAにいます。</p>

  )
}

export default PageA

ページB

src\page\PageB.js
import React from 'react'

const PageB = () => {
 
  return (
 
    <p>ページBにいます。</p>
 
  )
}
 
export default PageB

ページC

src\page\PageC.js
import React from 'react'

const PageC = () => {

  return (
 
    <p>ページCにいます。</p>
 
  )
}
 
export default PageC

ページD

src\page\PageC.js
import React from 'react'

const PageD = () => {
 
  return (
 
    <p>ページDにいます。</p>
 
  )
}
 
export default PageD

404ページ

src\page\Page404.js
import React from 'react'
 
const PageA = () => {
 
  return (
 
    <p>ページが見つかりません</p>
 
  )
}
 
export default PageA

表示確認

ブラウザのURLを変更して表示が切り替わるか確認します。

URL 表示内容
http://localhost:3000 ページAが表示される
http://localhost:3000/pageb ページBが表示される
http://localhost:3000/pagec ページCが表示される
http://localhost:3000/paged ページDが表示される
http://localhost:3000/適当な文字列 404ページが表示される

※ホスト名は環境によって変更してください

ページ間のリンク

Linkタグでの遷移

Linkのインポート

発リンクするコンポーネントのファイルでLinkをインポートします。

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

Linkコンポーネントのtoに指定できる形式

  • 文字列形式 
  • オブジェクト形式
文字列形式
jsx
<Link to="/pageb">リンクテキスト</Link>
 
//パラメータを渡す事もできます。
<Link to="/pageb?sort=name">リンクテキスト</Link>
オブジェクト形式
Link要素に指定できるオブジェクトのプロパティ 内容
pathname パスネーム
search パラメータ
hash ハッシュ
state ユーザ定義のデータ
jsx
<Link
  to={{
    pathname: "/pageb",
    search: "?sort=name",
    hash: "hash",
    state: { key: "value" }
  }}
/>

aタグでの遷移

Linkタグは、コンパイル後aタグになるのでaタグで書く事もできます。

内部リンク

jsx
//下記のコードはHTMLに変換するとaタグになるので、直接aタグで記述することもできる
<Link to="/pageB" >ページBへ</Link>

//↓と同じ結果になる

<a href="/pabeB">ページBへ</a>

外部サイトへのリンク

外部リンクはaタグで書きます。

js
<a href="https://qiita.com/" >Qiitaへ</a>

リンクのサンプル

src\page\PageA.js
import React from 'react'
 
//Linkをインポート
import { Link } from "react-router-dom";

const PageA = () => {

  return (
 
    <>
      <p>ページAにいます。</p>
      <p><Link to="/pageb">ページBへ</Link></p>
      <p><a href="https://qiita.com/" target="_blank" rel="noreferrer">Qiitaへ</a></p>
    </>
 
  )
}
 
export default PageA

react-router-domのフック

  • useHistory
  • useLocation
  • useParams
  • useRouteMatch

useHistory

historyオブジェクトを返します。

historyオブジェクト
history.push URL変更
history.goBack 履歴を戻る
history.location historyオブジェクトのプロパティからlocationオブジェクトを取得できる

 

useLocation

locationオブジェクトを返します。

locationオブジェクト 内容
location.pathname 現在のパス名
location.search 現在のパラメータ
location.hash 現在のハッシュ値
location.state ユーザ定義のデータ

historyとlocationの違い

URL変更時の挙動 内容
history 常に同じオブジェクト
location 新しいオブジェクトが作られる
useLocation/useHistory 使い分け
useLocation レンダリング中にlocationが必要なときに使う
useHistory レンダリング中にlocationが必要ないときに使う

hitstory.pushでの遷移のサンプル

onClickなどのhandleではLinkタグ、aタグが使えないので、history.pushで遷移させます。
history.pushもLinkタグと同じく文字列とオブジェクトでの遷移先の指定ができます。

ルーター

src\App.js
//追加でuseHistoryをimport
import { BrowserRouter, Route, Switch,useHistory} from "react-router-dom";

//各ページに相当するコンポーネントをインポート
import PageA from './page/PageA';
import PageB from './page/PageB';
import PageC from './page/PageC';
import Page404 from './page/Page404';

function App() {

  //historyの取得
  const history = useHistory();

  return (

    { /* BrouserRouterにhistoryを追加 */ },
    <BrowserRouter history={history}>

      <Switch>

        <Route exact path="/" component={PageA} />
        <Route exact path="/pageb" component={PageB} />
        <Route exact path="/pagec" component={PageC} />
        <Route exact path="/paged" component={PageC} />
        <Route component={Page404} />

      </Switch>

    </BrowserRouter>

  );

}

export default App;

発リンクするコンポーネント側

src
import React from 'react'

//追加でuseHistoryをインポート
import { Link,useHistory } from "react-router-dom";

const PageA = () => {

  //historyの取得
  const history = useHistory();

  return (

    <>
      <p>ページAにいます。</p>
      <p><Link to="/pageb">ページBへ</Link></p>

      <p
         onClick={() => {
           history.push("/pagec");
         }}
       >
         ページCへ
       </p>

      <p><a href="https://qiita.com/" target="_blank" rel="noreferrer">Qiitaへ</a></p>
    </>

  )
}
 
export default PageA

locationを指定した情報の表示のサンプル

ページA
Link要素で、オブジェクト形式で情報を付加して、ページDにリンクします。

src\page\PageA.js
import React from 'react'

//追加でuseHistoryをインポート
import { Link,useHistory } from "react-router-dom";

const PageA = () => {

  //historyの取得
  const history = useHistory();

  return (

    <>
      <p>ページAにいます。</p>
      <p><Link to="/pageb">ページBへ</Link></p>

      <p
         onClick={() => {
           history.push("/pagec");
         }}
       >
         ページCへ
       </p>

       <p
         onClick={() => {
           history.push({
             pathname:"/paged",
             search: "?sort=aaa",
             hash: "#hash",
             state: { test: "成功" }
            });
         }}
       >
         ページDへ
       </p>

      <p><a href="https://qiita.com/" target="_blank" rel="noreferrer">Qiitaへ</a></p>
    </>

  )
}

export default PageA

ページD
渡した情報が表示されます。

src/page/PageD.js
import React from 'react'

import { useLocation } from "react-router-dom";

const PageD = () => {

  const location = useLocation();

  return (

    <>
      <p>ページDにいます。</p>

      {/* locationで情報を表示します。 */}
      <p>pathname: {location.pathname}</p>
      <p>search: {location.search}</p>
      <p>hash: {location.hash}</p>
      <p>state.test: {location.state.test}</p>

    </>

  )

}

export default PageD

useParams

URLのパスの中で動的に変化する部分の値を取得できます。

パラメータによって表示を変更するサンプル

ルーター
ページEへのリンクを追加(パラメータを付与できるようにする)

src\App.js
import { BrowserRouter, Route, Switch,useHistory} from "react-router-dom";

import PageA from './page/PageA';
import PageB from './page/PageB';
import PageC from './page/PageC';
import PageD from './page/PageD';
import PageE from './page/PageE';
import Page404 from './page/Page404';

function App() {

  const history = useHistory();

  return (

    <BrowserRouter history={history}>

      <Switch>

        <Route exact path="/" component={PageA} />
        <Route exact path="/pageb" component={PageB} />
        <Route exact path="/pagec" component={PageC} />
        <Route exact path="/paged" component={PageD} />

        {/* ページEへのリンクを追加(idというパラメータをつける) */}
        <Route exact path="/pagee/:id" component={PageE} />
        <Route component={Page404} />

      </Switch>

    </BrowserRouter>

  );

}

export default App;

ページA
ページEへのリンク追加

src\page\PageA.js
import React from 'react'

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

const PageA = () => {

  const history = useHistory();

  return (

    <>
      <p>ページAにいます。</p>
      <p><Link to="/pageb">ページBへ</Link></p>

      <p
         onClick={() => {
           history.push("/pagec");
         }}
       >
         ページCへ
       </p>

       <p
         onClick={() => {
           history.push({
             pathname:"/paged",
             search: "?sort=aaa",
             hash: "#hash",
             state: { test: "成功" }
            });
         }}
       >
         ページDへ
       </p>

      {/* ページEにリンク(パラメータ違いで3つ)*/}
      <p><Link to="/pagee/yamada">ページEへ(yamada)</Link></p>
      <p><Link to="/pagee/sato">ページEへ(sato)</Link></p>
      <p><Link to="/pagee">ページEへ(パラメータなし)</Link></p>

      <p><a href="https://qiita.com/" target="_blank" rel="noreferrer">Qiitaへ</a></p>
    </>

  )
}
 
export default PageA

ページE
新規作成

src\page\PageE.js
import React from 'react'

//useParamをインポート
import { useParams } from "react-router-dom";

const PageE = () => {

  //パラメータを取得
  const {id} = useParams();

  return (

    <>
      <p>ページEにいます。</p>

      {/* 受け取ったパラメータを表示 */}
      <p>ID:{id}</p>
    </>

  )
}

export default PageE

useRouteMatch

パラメータによってコンポーネント単位でレンダリングの制御ができます。

パラメータによってコンポーネントを出し分けるサンプル

ページEを変更します。

src\page\PageE.js
import React from 'react'

//useRouteMatchをインポート
import { useRouteMatch  } from "react-router-dom";

const PageE = () => {

  //条件の指定
  const matchYamada = useRouteMatch('/pagee/yamada');


  return (

    <>
      <p>ページEにいます。</p>

      {/* パラメータがyamadaのとき表示するコンポーネント */}
      {matchYamada ? <p>IDがyamadaなので表示されています</p> : null}

    </>

  )
}
 
export default PageE
20
18
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
20
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?