reactjs
React
react-router
redux

React Router v4とReduxを繋げるにはconnected-react-routerを使うのがおすすめだよ!

今、Railsをバックエンド、ReactをフロントエンドにWebサービスを作っています。

Reactでは、ステート管理にRedux、ルーターにReact Router v4を使っています。

そこで、React Router v4のステートをReduxで管理したいのです。


どうやってReact Router v4のステートをReduxで管理するか


よくみんなが使ってるライブラリ react-router-redux

現在、react-router-reduxは、最新版のはReact Router v4に対応しておらず、alpha版の5系にReact Router v4は対応してるようです。 

しかし、React RouterのGithubリポジトリをみて見ると、react-router-reduxは、メンテナンスされていなく、非推奨であるそうです。


ということでreact-router-redux を使うのはやめた

そして、React RouterのGithubリポジトリでは、ReduxとReactを同期させるためのライブラリはとして、 connected-react-routerが紹介されています。


React Router推奨のconnected-react-routerを使うことにした

使い方はconnected-react-routerのREADMEで紹介されています。


connected-react-routerのいいところ



  • react-router v4をサポートしてる

  • ステートを維持しながらホットリロードすることをサポートしてる


  • redux-thunk,redux-sagahistoryメゾットのdispatchが機能する

  • TypeScriptをサポートしてる


connected-react-routerの使い方


Step1



  • historyオブジェクトを作る

  • ルートレデューサーをconnectRouterでラップし、historyオブジェクトを指定して新しいルートレデューサーを取得する


  • historyアクションを送出する場合(push('/path/to/somewhere')など)にURLを変更する場合は、 routerMiddleware(history)を使う。

...

import { createBrowserHistory } from 'history'
import { applyMiddleware, compose, createStore } from 'redux'
import { connectRouter, routerMiddleware } from 'connected-react-router'
...
const history = createBrowserHistory()

const store = createStore(
connectRouter(history)(rootReducer), // new root reducer with router state
initialState,
compose(
applyMiddleware(
routerMiddleware(history), // for dispatching history actions
// ... other middlewares ...
),
),
)


Step2


  • React Routerv4のルーティングをConnectedRouterでラップし、historyオブジェクトをpropsとして渡す


  • ConnectedRouterをreact-reduxのProviderの子として配置する

...

import { Provider } from 'react-redux'
import { Route, Switch } from 'react-router' // react-router v4
import { ConnectedRouter } from 'connected-react-router'
...
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}> { /* place ConnectedRouter under Provider */ }
<div> { /* your usual react-router v4 routing */ }
<Switch>
<Route exact path="/" render={() => (<div>Match</div>)} />
<Route render={() => (<div>Miss</div>)} />
</Switch>
</div>
</ConnectedRouter>
</Provider>,
document.getElementById('react-root')
)