React Router v4で任意のid情報を送る方法

## 概要

コロコロとバージョンが変わるReact Router。
今回は現在最新バージョンであるreact-router-dom@4.2.2を使ってみたのでメモに残します。

詳細
https://reacttraining.com/react-router/
https://www.npmjs.com/package/react-router-dom

まだreact-router-domを入れていない人は下記コマンドを実行してください。

```
yarn add react-router-dom
```

今回はRailsなどのWebアプリケーションでよく使う、URLに任意のid情報を送る方法を紹介します。
Railsでおなじみの

```
/users/:id: 
```

のような書き方をReact Routerで表現して見ました。
とりあえずサンプルコードを載せます。

サンプルの動き
https://gyazo.com/c99338a35c7bad25d3f15fe7214a3a5b


```サンプルコード
import React, { Component } from 'react';
import {
  BrowserRouter as Router,
  Route,
  Link,
  Switch
} from 'react-router-dom'

const flowers = [
  {id: 1, name: "ひまわり"},
  {id: 2, name: "たんぽぽ"},
  {id: 3, name: "バラ"}
]

const App = () => (
  <Router>
    <div>
      <Switch>
        <Route
          exact path="/"
          component={FlowerLists} 
　　　   />
        <Route
          path='/flower/:id'
          component={OneFlower} 
        />
        <Route
          component={NoContents} 
        />
      </Switch>
    </div>
  </Router>
);

const NoContents = () => (
  <div>No Contents!!</div>
)

const FlowerLists = () => {
  const flowerLists = flowers.map(e => (
    <li key={e.id}>
      <Link to={'/flower/' + e.id}>{e.name}</Link>
    </li>
  ));
  return (
    <ul>
      {flowerLists}
      <Link to={'/nocontents'}>No contents</Link>
    </ul>
  )
};

class OneFlower extends React.Component {
  render() {
  	(① console.log(this.props))
    const params = this.props.match
    const id = parseInt(params.params.id, 10)
    const flower = flowers.filter(e => e.id === id)[0]
  return (
      <div>{id}: {flower.name} </div>
    )
  }
}

export default App;

```

Route、Link、Switchについて見ていきます。

## Routeについて

```Routeコンポーネント
<Route
    exact path="/"
    component={FlowerLists} />
```

まずはexactの説明

```
exact path="/"　・・・　pathが完全に"/"の時にFlowerListsコンポーネントを表示する。(完全一致)
path="/" ・・・ pathの先頭が"/"だったらFlowerListsコンポーネントを表示する。(前方一致)
```
このように、もしもexactがないと、/で始まる全てのpathでFlowerListsコンポーネントが表示されてしまいます。
exactは忘れないようにしましょう。


そして、今回はRouteコンポーネントを用いて、以下のように各flowerのidを渡しました。

```
<Route
	path='/flower/:id'
	component={OneFlower} />
```

このように設定することとうまくいきます。
例えば `/flower/2` でアクセスすると、:idには2が入り、propsとしてOneFlowerコンポーネントに2が渡されます。
上記の①のconsole.log(this.props)の中身を見て確認してみましょう。

```上記の①のconsole.log(this.props)の中身
props {match: {…}, location: {…}, history: {…}, staticContext: undefined}
		▶︎history: {length: 8, action: "PUSH", location: {…}, createHref: ƒ, push: ƒ, …}
		▶︎location: {pathname: "/flower/2", search: "", hash: "", state: undefined, key: "jnv2ih"}
		▼match:
		 isExact: true
		 ▶︎params: {id: "2"}
		 path: "/flower/:id"
		 url: "/flower/2"
		 ▶︎__proto__: Objects
		 taticContext: undefined
		▶︎__proto__: Object
```

となっているので、:idの部分を取得したい場合は

```:idの取り出し方
this.props.match.params.id
```

となります。簡単ですね。

## Switchについて

SwitchはRouteの中で指定していないpathにアクセスした時に、pathを指定していないRouteコンポーネントを表示させることができます。

```pathを指定していないこのRouteコンポーネントがSwitchによって動く
<Route
  component={NoContents} />
```

例の場合だと、上記のNoContentsコンポーネントが,「/」や「/flower/:id」以外にアクセスすると表示されるようになります。


## Linkについて

```Linkコンポーネントはaタグと同じ
<Link to={'/flower/' + e.id}>{e.name}</Link>
```

Linkはaタグと同じ機能を果たします。to=で書かれたpathにgetリクエストを送信します。

## あとがき

React Routerは本当に便利ですね。これ以外にも便利な使い方があるみたいなので、皆さんも便利なReact Routerライフを送りましょう。