React Router v4を使う

#目次
- ルーティングの概念
- 基本的なルーティング
- 少し応用

> React Router v4
>https://reacttraining.com/react-router/

##ルーティングの概念
普通のHTMLではaタグで使ってその際に別ページのHTML、CSS、JSのファイルを取ってくる為のリクエストとレスポンスが走ります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/229570/ac2e1c6b-e790-c22c-783e-8413e3ca2875.png)

しかしSPA(シングルページアプリケーション)場合はそうではありません。
Webpackと呼ばれるモジュールバンドラでプロジェクト内で使われている全てのコンポーネントを一つのJSファイルに書き出します。(設定は色々できます。)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/229570/09b8ad4a-ff55-adbe-af6c-cba5e8a581ab.png)

Reactアプリをみてみます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/229570/7424ee34-78b6-47e7-fb29-ec27ba1e766b.png)
ただh1の文字にReactロゴのSVGだけのページです。
ソースは見ると、、

![image.png](https://qiita-image-store.s3.amazonaws.com/0/229570/1a4bc1ef-6492-f0b7-2686-7795578e3e94.png)

どこにもh1もReactLogoのSVGもないですよね。

次に、./static/js/bundle.jsをみてみます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/229570/afa4d88e-8c84-c46a-6089-ff1b4b1214d6.png)
すると中に何万行もの記述があり、写真の38362行目に`'React Router\u3092\u899A\u3048\u308B'`ってありますね。
これが日本語がユニコードで変換されており、38353行目に`createElement(
          'h1'~,`とあります。


もう分かりましたよね？
**ReactではWebpackによってまとめられた１つのJSファイルをの中から必要な要素をJavascriptで動的に生成しています。**
もちろんページごとに１つづつ作られる訳ではなくプロジェクトで１つのjsファイルでWebpackから吐き出されます。


なので、ルーティングでページが変わった時は、リクエスト、レスポンスは走らずJSで動的にDOM要素を生成します。
しかもその際に前にお話しした仮装DOMで差分を測って差分のみを更新する訳です。
速い訳ですよね。。


##基本的なルーティング
コード自体は単純でそんなに難しくないと思います。

```

まずはreact-routerのインストール
npm install -S react-router-dom
```

色々な書き方がありますが、個人的に好きな書き方で書きます。

srcディレクトリの中にルーティングを定義するだけのコンポーネント、`Routing.js`を作成します。

```js:Routing.js
import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom'
import App from './App';

class Routing extends React.Component {
  render() {
    return (
      <BrowserRouter>
        <Switch>
          <Route exact path="/" component={App} />
        </Switch>
      </BrowserRouter>
    )
  }
}

export default Routing;
```

これを`index.js`で呼び出します。

```js:index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import registerServiceWorker from './registerServiceWorker';
import Routing from './Routing';

ReactDOM.render(<Routing />,document.getElementById('root'));
registerServiceWorker();
```

すると最初と同じ画面が出ます。
このまま続きます。
別ページ`About.js`を作ります。

```js:About.js
import React from 'react';
import { Link } from 'react-router-dom';

const About = () => (
  <div>
    <h1>About</h1>
    <p>Aboutページです。</p>
    <Link to="/">Homeへ戻る</Link>
  </div>
)

export default About;
```

`Routing.js`で読み込みます

```js:Routing.js
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import App from './App';
import About from './About';


class Routing extends React.Component {
  render() {
    return (
      <BrowserRouter>
        <Switch>
          <Route exact path="/" component={App} />
          <Route exact path="/about" component={About} />
        </Switch>
      </BrowserRouter>
    )
  }
}

export default Routing;


```

`App.js`修正します

```js:App.js
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import logo from './logo.svg';
import './App.css';


class App extends Component {
  render() {
    return (
      <div className="App">
        <h1>React Routerを覚える</h1>
        <img src={logo} className="App-logo" alt="logo" />
        <div>
          <Link to="/about">About</Link>
        </div>
      </div>
    );
  }
}

export default App;

```

これでブラウザを開くと無事リンクが通ってます。

**解説**

`<BrowserRouter>`
React Router使いますよ。って宣言的なものだと思ってください。
React Router使うときのお約束です。
1プロジェクトに1回だけ使います。
これを通すと子要素にpathの情報やページ遷移に使う関数などが渡されていきます。

`<Switch>`
これが口だと言いづらいのですが、まぁ最初はおまじないとして、`Route`を使うときには外で囲んであげてください。

`<Route>`
pathに合わせてコンポーネントを入れ替えてくれます。
exactは全体一致、つけないとpath以降は先頭一致になります。

`<Link>`
リンク遷移したい時はaタグは使わず、このタグを使います。
toに遷移したい先を書く。


##少し応用








疲れたので今度描きます笑