何のためにreact-router-reduxを使うのか復習しようとしたら、deprecatedになっていた

# 概要

なんとなくの理解で使っているreact-router-reduxを復習しようと思い立ったところ、今やreact-router-reduxはdeprecatedになっていました。あらー。
今、React Routerのドキュメント（[Redux Integrationのページ](https://reacttraining.com/react-router/web/guides/redux-integration)）を見ると、代わりに[Connected React Router](https://github.com/supasate/connected-react-router)というライブラリが紹介されています。

とはいえ、React RouterとReduxの統合は何のためか、という目的はどちらのライブラリもそう変わらないはずですので、この機会に復習していきます。
その上で、今度からはConnected ... の方を使おうと思います。

# 現状、こんな風に使ってた

私が書いていたコードをかいつまむと、以下の通りです（だいぶ省略してます）。
redux-thunkによる非同期アクションにおいて遷移の処理を呼びたくて、react-router-reduxを使っていました。

```jsx:App.jsx（ここは特筆する点は無し）
// React Router関連
import createHistory from 'history/createHashHistory'
import { Switch, Route } from 'react-router-dom'
// react-router-redux関連
import { ConnectedRouter, routerMiddleware } from 'react-router-redux'

// historyを作って・・・
const history = createHistory()

// Reduxのミドルウェアを設定したり・・・
const middlewares = [routerMiddleware(history), ... ]
const store = createStore(reducer, applyMiddleware([...middlewares))

// ConnectedRouterとかSwitchといったコンポーネントを並べたり・・・
const App = () => (
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <Switch>
        {/* Switchの下に、Routeがいくつか並ぶ・・・ */}
      </Switch>
    </ConnectedRouter>
  </Provider>
)
```

```js:ActionCreatorはこんな感じ（redux-thunkによる非同期アクションの中で、pushを使ってルーティング）
// 何やら便利なpushなるものをimport
import { push } from 'react-router-redux'

export const sampleAsyncAction => async (dispatch) => {

  // 非同期処理とかやったあとに・・・

  dispatch(push('/samplePath')) // 次の画面へ遷移する
}
```

# 改めてReact Routerのドキュメントに立ち返る

改めて、React Router公式の[Redux Integrationのページ](https://reacttraining.com/react-router/web/guides/redux-integration)を見るのですが、どうも難しそうなことが書いてあります。

何度か読んでいるうちに、以下の理解が得られました。

- Reduxとの統合は必ずしも必要ではない。`<Link>`などで事足りるなら不要。
- アクションのディスパッチによって遷移を起こしたい時などに、統合が必要となる。例えばredux-thunkやredux-sagaによって非同期処理を行った後に、遷移したい時（今回の私のケースはこれ）。
- そうした場面では、アクションをディスパッチする際に[history](https://reacttraining.com/react-router/core/api/history)を触れる状況を作ればよい。そうすれば、history.push(...)などのメソッドを呼んで各種遷移を起こせる。

# react-router-reduxは手段の一つ

何らかの手段によって、アクションのあたりでhistoryを触れれば良い、という風にいったんまとめられそうです。
その手段の一つが、react-router-reduxのようなライブラリを導入することなのでしょう。

先ほどのコード例で登場したように、react-router-reduxには`push`のような便利関数があります。

```js
import { push } from 'react-router-redux'
```

ソースを見たところ、以下の様にして遷移が行われるようでした。

1. pushを呼ぶと、アクションが作られる（アクションのtypeは、react-router-reduxの中にハードコードされている）。
2. そのアクションがディスパッチされると、react-router-reduxが提供しているrouterMiddlewareがそれに反応する。
3. そしてrouterMiddlewareがhistory.pushを呼ぶ。最初にApp.jsxにて、`routerMiddleware(history)`という風に呼び出しているので、routerMiddlewareはhistoryを触れるというわけ。

# Connected React Routerも使用感は同じ

まだ熟読していないのですが、代替であるConnected React Routerも使い方はほぼ変わらなさそうです。

- 一番最初に、Reduxのミドルウェアなどを仕込んでおく。
- Reduxの`<Provider>`の下に、`<ConnectedRouter>`を置いておく。
- pushなどをimportし、ActionCreatorにおいて利用する。

# まとめ

先ほど、何らかの手段によってアクションの近辺でhistoryを触れれば良い、という風にいったんまとめました。
historyがもつpushなどのメソッドによって、遷移を起こせます。

react-router-reduxやConnected React Routerといったライブラリを使うと、好きな箇所でpushなどを呼べるようになります。例えば非同期アクションの中などで使えて便利です。

一方、やろうと思えばこれらのライブラリなしでもhistoryを触ることはできそうです。

- `<Route>`のcomponentなどには、引数としてhistoryが渡されるので（[参照](https://reacttraining.com/react-router/core/api/Route/route-props)）、そのhistoryを親コンポーネントから子コンポーネントへと渡しまくっていき、最終的にActionCreatorの引数として渡す。
- あるいは、要所要所のコンポーネントを[withRouter](https://reacttraining.com/react-router/core/api/withRouter)で囲んでおく。withRouterで囲んでおくと、コンポーネントのpropsとしてhistoryが渡される。それを同じくActionCreatorに渡す。

とはいえこれは面倒ですので、ライブラリを使うと便利ですよ、ということなのでしょう。