74
42

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2018-10-14

概要

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

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

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

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

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>
)
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のページを見るのですが、どうも難しそうなことが書いてあります。

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

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

react-router-reduxは手段の一つ

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

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

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が渡されるので(参照)、そのhistoryを親コンポーネントから子コンポーネントへと渡しまくっていき、最終的にActionCreatorの引数として渡す。
  • あるいは、要所要所のコンポーネントをwithRouterで囲んでおく。withRouterで囲んでおくと、コンポーネントのpropsとしてhistoryが渡される。それを同じくActionCreatorに渡す。

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

74
42
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
74
42

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?