JavaScript
reactjs
Router

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

More than 1 year has passed since last update.

概要

コロコロとバージョンが変わる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
    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コンポーネントを表示させることができます。

<Route
  component={NoContents} />

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

Linkについて

<Link to={'/flower/' + e.id}>{e.name}</Link>

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

あとがき

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