React + Redux環境でReact Routerを使っていると、ページ遷移のタイミングで困ることがあると思います。
特に非同期通信を行う場合は、通信が終了したタイミングでページ遷移をしたい場合があると思います。
これはaction creator内でページ遷移が可能になれば、実現できます。
その方法を解説していきます。
historyを使う
historyというライブラリを使用することで簡単に実現出来ます。ドキュメント曰く
履歴ライブラリを使用すると、JavaScriptが実行されている場所でセッション履歴を簡単に管理できます。 履歴はさまざまな環境の違いを抽象化し、セッション間で履歴スタックの管理、ナビゲート、状態の維持を可能にする最小限のAPIを提供します。
by Google翻訳
historyはReact Routerと全く別のライブラリというわけではなく、React Routerの内部で使われているライブラリなのでReact Routerをインストールしていればすでに使用可能になっています。
以下のようにhistory用のファイルを作成します。
import { createBrowserHistory } from "history"; export const browserHistory = createBrowserHistory();
このbrowserHistoryをインポートして使うことで、action creator(React コンポーネント以外で)pushやgoBack等が可能になります。
React Routerでhistoryインスタンスを使う
ただしその前にReact RouterのRouterにhistoryインスタンスを渡してあげる必要があります。
ポイント
BrowserRouterではなくRouterを使うこと
import { Router } from "react-router-dom"; import { browserHistory } from "./history"; <Router history={browserHistory}> // Switch、Routeは通常通り </Router>
後は実際にページ遷移のコードを書くだけです。
Action Creatorでページ遷移
action creator内で非同期通信の終了を待ってからページ遷移をしてみます。
以下は一例です。
redux-thunkを使っています
import { browserHistory } from "../history"; // historyインスタンスをインポート export const hogeHoge = data => async dispatch => { try { await axios.post("/somewhere", data); // 非同期通信 dispatch(successHogeHoge(data)); browserHistory.push("/somewhere"); // ページ遷移 } catch (error) { dispatch(apiFailed("FugaFuga")); browserHistory.push("/error"); } };
以上です。