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");
}
};
以上です。
