react-routerが都合よくAPIを公開してくれた!(がダメだった)

mk.hatenablog.com

かなり前ですけど、react-routerのURLをreduxで管理していい感じ、というコード書きました。こちらはreact-routerの非公開関数を利用していたので将来危険だなあと思ってましたが、react-router 4.xでやっぱりダメになりました。しかしそれは良い方向の変更で、利用していた非公開関数の同等機能をきちんとAPIにしてくれてたのです。

該当箇所は以下のとおりに元記事のReducer内のヘルパ関数の中身を書き直します。申し訳ないのは元記事ではtitleをURI内パラメータ、pageをクエリー値でもってくる仕様だったのを、title、vol、pageを全部URIエンコードされている仕様に変更してたわ。

import { matchPath } from 'react-router-dom';

const decodeTitleAndPage = (pathname) => {
    const m = matchPath(pathname, '/:title/:vol/:page');
    if (m) {
        const strPage = m.params.page;
        const numPage = strPage ? Number(strPage) : 0;
        return { ...m.params, page: numPage };
    }
    return {};
};

ダメだった

おっとどっこい。react-router-reduxがreact-routerの最新バージョンに追いついていない!動いていたみたいなのはブラウザのキャッシュが効いてただけでした。テストを走らせたら爆発して気づき、キャッシュクリアしたらちゃんとアプリも壊れました。そっと上の修正をもどして、react-routerも3.0.5にもどしました。

なにやらreact-router-reduxがreact-routerにマージされていくような様子?5.xでちゃんとするようなことが書いてあった。きちんとバージョン上がったときへの備忘録として記事は残しておきます。

react-router-redux 5.x での変化

ちょっと見てみた。

export const LOCATION_CHANGE = '@@router/LOCATION_CHANGE'

export function routerReducer(state = initialState, { type, payload } = {}) {
  if (type === LOCATION_CHANGE) {
    return { ...state, location: payload }
  }

  return state
}

react-router-reduxのrouterReducerのAction仕様が変わってる。反応するtypeの文字列が ‘@@router/LOCATION_CHANGE’ になってるし、パラメータ名が ‘location’ になってる。3.xではそれぞれ ‘locationChange’ と ‘locationBeforeTransitions’ 。まずこれだけで動くわけがない。さらにはReduxのミドルウェアを利用したり、Reactコンポーネントが提供されたり、そもそものアーキテクチャが変わっていた。