React-RouterとReduxを同時に使うときの注意点が次のドキュメントにあります。Redux Integration - REACT TRAINING / REACT ROUTER。多くの場合問題なく使えるが、注意点もある。withRouterを使えば解決できる。というような趣旨ですが、あまり明確に理解できなかったので実験を行いました。
問題はprops.historyが機能しない場合があるというものです。以下のソースコードで試してみました。props.historyは<Route>を通した場合に有効になるものです。それ以外だとwithRouterで使えるようになります。
src/App.js
import React from 'react';
import {Route, Link, withRouter} from 'react-router-dom'
import { connect } from 'react-redux'
const App = () =>
<div>
<Route exact path="/" component={Home} />
<Route path="/comp1" component={Comp1} />
<Route path="/comp5" component={Comp5} /> -- 5-1
<Route path="/comp6" component={Comp6} /> -- 6-1
<Route path="/comp7" component={Comp7} /> -- 7-1
</div>
const Home = () => (
<div>
<Link to="/comp1">Comp1</Link><br />
<Link to="/comp5">Comp5</Link><br /> -- 5-2
<Link to="/comp6">Comp6</Link><br /> -- 6-2
<Link to="/comp7">Comp7</Link> -- 7-2
</div>
)
const Comp1 = (props) =>
<div>
<button onClick={() => props.history.goBack()}>
Comp1
</button><br />
<Comp5 /><br />
<Comp6 /><br />
<Comp7 /><br />
</div>;
// --- ラッピングなしの通常のComponent
const Comp5 = (props) =>
<button onClick={() => props.history.goBack()}>
Comp5
</button>
// --- connnectラッピングのComponent
const Comp6 = connect()(
(props) =>
<button onClick={() => props.history.goBack()}>
Comp6
</button>
)
// --- withRouter+connnectラッピングのComponent
const Comp7 = withRouter( connect()(
(props) =>
<button onClick={() => props.history.goBack()}>
Comp7
</button>
))
export default App
<Route>を通せばすべてのケース(5-1, 6-1, 7-1)で成功した。
<Link>の場合は、withRouterでラッピングした7-2だけが成功し、5-2と6-2は失敗した。これってあまりReduxの問題ではないような気がしますが。
以上ですが、念のため環境構築と他のソースも掲載しておきます。
npx create-react-app redux-react-router
cd redux-react-router
npm i --save redux react-redux react-router-dom
rm -rf src
src/index.js
import React from 'react';
import { render } from 'react-dom';
import {BrowserRouter} from 'react-router-dom'
import App from './App';
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import rootReducer from './reducer'
const store = createStore(rootReducer)
const target = document.getElementById('root');
const node =(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
);
render(node, target);
src/reducer.js
export default (state = {}, action) => {
switch (action.type) {
default:
return state;
}
}
以上です。