React Routerのざっくり概要

# この記事の目的
[公式ページのガイド](https://reacttraining.com/react-router/web/guides/quick-start)を見てもらうのが一番だが、公式は英語の情報しかないためReact Routerを使用するにあたって押さえておきたいポイントをかいつまんで説明する。

# 参考資料
[公式ガイド](https://reacttraining.com/react-router/web/guides/quick-start)

# React Routerのざっくり概要
## React Routerとは
ReactでSPA（Single Page Application）を実現し、SPAのルーティングを管理するためのモジュール。
Reactのルーティングライブラリは過去にいくつか出ては消えてを繰り返してきたが、現在はReact Routerがデファクトスタンダードと言える。

## 基本的な使い方
### 画面の構成例
[Material UIのテンプレートページ](https://material-ui.com/ja/getting-started/templates/)で紹介されている、以下の画面構成を例にReact Routerの使い方を説明する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/62db6e67-c2bf-945e-c82c-c366d06d268d.png)

## 画面の構成例をコンポーネント単位に分解
上記の画面は、コンポーネント単位に分解すると以下のような構成となる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/afa80d38-3af3-1363-c7e0-795a914aa0cf.png)

左端のDrawerコンポーネントにメニューがあり、メニューを選択するとmainタグの領域にコンテンツを表示する。
このとき、ページ遷移（HTMLのhttpリクエスト・レスポンス）は発生せず、DrawerコンポーネントとAppBarコンポーネントの表示はそのままにmain領域のコンテンツだけを入れ替える動作となる。

ページ遷移（HTMLのhttpリクエスト・レスポンス）を行わないでコンテンツの入れ替えを行うので、SPA（Single Page Application）となっている。

## React Routerをコードに仕込む例
上記の画面例をReact Routerで実現する場合のコード例を示す。

### コードの例

```jsx:app.tsx
// ※説明に必要なステップ以外は省略している

import React from "react";
import Dashboard from "./components/Top";
import About from "./components/About";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";  //ポイント1

const App: React.FC = () => {
  return (
    <Router>  //ポイント2
      // AppBar
      <AppBar>
      </AppBar>
      // Drawer
      <Drawer>
        <List>
          <ListItem button component={Link} to={/}>  //ポイント3a
            <ListItemText primary="Dashboard" />
          </ListItem>
        </List>
        <List>
          <ListItem button component={Link} to={/about}>  //ポイント3b
            <ListItemText primary="About" />
          </ListItem>
        </List>
      <Drawer>
      // main
      <main>
        <Switch>  //ポイント4a
          <Route exact path="/">  //ポイント4b
            <Dashboard />
          </Route>
          <Route exact path="/about">  //ポイント4c
            <About />
          </Route>
        </Switch>
        <main>
    </Router>
  );
};

export default App;
```

### 注目すべきポイント
ポイントは以下の4点。

1. `react-router-dom`をインポートする
1. メニュー領域（この例の場合Drawerコンポーネント）とコンテンツ領域（この例の場合はmainタグ）を`<Router>`タグで囲む（Routerコンポーネントの一部として扱われる）
1. メニュー領域（Drawerコンポーネント）
 1. メニューから「Dashboard」を選択した場合、`/`にルーティングすることを定義している
 1. メニューから「About」を選択した場合、`/about`にルーティングすることを定義している
1. コンテンツ領域（mainタグ）
 1. コンテンツを表示する領域を`<Switch>`タグで囲む（Switchコンポーネントの一部として扱われる）
 1. `<Route>`タグでルーティングを定義する。この場合、`/`にルーティングしたらmainタグの領域にDashboardコンポーネントを表示するように定義している
 1. `<Route>`タグでルーティングを定義する。この場合、`/about`にルーティングしたらmainタグの領域にAboutコンポーネントを表示するように定義している

## 応用的な使い方
### イベント起因でルーティング
基本的な使い方では、Linkコンポーネントを使ってボタンを押したらルーティングする方法を取ったが、ルーティングHistoryに直接パスを追加するとこでonClickイベントなどのイベント起因でルーティングすることも可能。

#### コードの例

```jsx:order.tsx
// ※説明に必要のないステップは省略している

import React from "react";
import { withRouter } from 'react-router';  //ポイント1

class Orders extends React.Component {
  routingToAbout = () => {
    this.props.history.push('/about')  //ポイント3
  }

  render() {
    return (
      <div>
        <Button onClick={this.routingToAbout}> //ポイント2
          aboutへ移動
        </Button>
      </div>
    )
  }
}

export default withRouter(Orders)
```

#### 注目すべきポイント
ポイントは以下の3点。

1. インベント起因のルーティングではwithRouterコンポーネントを使用するので、`'react-router'`をインポートする
1. onClickイベントでルーティングしたいので、onClickイベントが発火したらコンポーネント内の関数を呼ぶように設定する
1. onClickイベントから呼ばれた関数内では、`this.props.history.push('/about')`でルーティングHistoryにaboutページへのルーティングを追加する。これによって、ルーティングHistoryの最後がaboutページになるので、aboutページに遷移することになる