react-routerのパスでハマった時のメモ

最近、Reactを使用する機会があり勉強しました。
脱JQueryを目指しReactを学習していたのですが、幾つか壁がありました。
その一つがreacr-routerでした。
パス設定でハマったときのメモを残しておきます。

記事は古いのですが、どうやら私と同じ所でハマった方がおられました。
[【React.js】react-routerでハマりやすいポイント](http://shibe97.tumblr.com/post/122678388082/reactjsreact-router%E3%81%A7%E3%83%8F%E3%83%9E%E3%82%8A%E3%82%84%E3%81%99%E3%81%84%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88)
react-routerの初心者あるあるのようですね。
しかし、上記の記事ではreact-router1.0以降の仕様とは異なるため、注意が必要。

* http://stackoverflow.com/questions/32806296/react-router-indexroute-vs-defaultroute
* http://stackoverflow.com/questions/36532369/react-router-routehandler-undefined

本記事では、[【React.js】react-routerでハマりやすいポイント](http://shibe97.tumblr.com/post/122678388082/reactjsreact-router%E3%81%A7%E3%83%8F%E3%83%9E%E3%82%8A%E3%82%84%E3%81%99%E3%81%84%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88)の内容をv1.0~にアップデートし考察します。

# react-routerのpath
ハマりポイントに関しては、[pathでアクセスした時の挙動](##pathでアクセスした時の挙動)を参照ください。
その他の項目で、react-routerの超基本的な話を整理します。
基本的なreact-routerの使い方はは、こちらの[react-routerでルーティング](http://smart.ataglance.jp/2016-01-07-react-router/)が非常にまとまっており、分かりやすかったです。

### react-routerのv.0.1~系とv1.0の違い
古い記事では`DefaultRoute`や`handler`などを使用しています。
バージョン間の違いは[こちらのページ参照](https://github.com/ReactTraining/react-router/blob/master/upgrade-guides/v1.0.0.md)

### ルーティングとネスト
コンポーネント内で`{this.props.children}`を用いることで、
pathにマッチするアクティブなRouteの子コンポーネントを呼び出すことができる。
親となるコンポーネントから、その他の全ての子コンポーネントを受け取りたい場合は、
`React.cloneElement`を用い、追加のpropsを注入することで実現できる。

```
import React from 'react';

export default class AAA extends React.Component {
    render() {
        return (
            <html>
                <head>
                    // 
                </head>
                <body>
                    {this.props.children && React.cloneElement(this.props.children, { someExtraProp: something })}
                </body>
                <script src="/bundle.js"></script>
            </html>
        );
    }
}
```

### pathでアクセスした時の挙動
pathは絶対パスで指定せず、親のRouteのパスからつながっていくように設定する。

```
import React from "react";
import {IndexRoute, Route, Router, hashHistory} from "react-router";

export default <Router history={hashHistory}>
    <Route path="/" component={AAA}>
        <IndexRoute component={BBB} />
        <Route path="bbb" component={BBB} />
        <Route path="ccc/:id" component={CCC}>
            <DefaultRoute component={DDD} />
            <Route path="ddd" component={DDD} />
            <Route path="eee" component={EEE} />
            </Route>
    </Route>
</Router>;
```
* ”/"にアクセスした場合
> AAAコンポーネントを見に行く
> 子階層を見に行く
> 親コンポーネントの定義しているpath`/`と一致しているので、IndexRouteが適用され、BBBコンポーネントを見に行く

* ”/bbb"にアクセスした場合
> AAAコンポーネントを見に行く
> 子階層を見に行く
> BBBコンポーネントを見に行く

* “/ccc/1234"にアクセスした場合

> AAAコンポーネントを見に行く
> 子階層を見に行く
> CCCコンポーネントを見に行く
> 子階層を見に行く
> 親コンポーネントの定義しているpath`/ccc/:id`と一致しているので、IndexRouteが適用され、DDDコンポーネントを見に行く

* ”/ccc/1234/ddd"にアクセスした場合

> AAAコンポーネントを見に行く
> 子階層を見に行く
> CCCコンポーネントを見に行く
> 子階層を見に行く
> DDDコンポーネントを見に行く

### 補足
* IndexRouteって何？
親コンポーネントの定義しているpathと一致したときにRoute

* HashHistory
react-routerの`BrowserHistory`を使うと`#`が入らない。
一方、`HashHistory`を使うと`#`が入る。


### 追記
Reactを学習する時に、一度に全部学習するのは大変です。
順を追って学習し、一つ一つハマリポイントを潰した方が良さそうです。

1. ES6の記法
2. React自体
2. bundle
3. JSX
4. react-router --->　本記事
5. flux