課題
- historyオブジェクトを利用して、ページをリダイレクトしたいがreduxを利用すると上手く動かない。
- console.logを仕込んでみると、どうやらhistoryオブジェクト自体がpropsとして渡されていないようだった。
環境
- node v12.7.0
- express 4.16.1
- react 16.12.0
- npm 6.10.2
- macOS Mojave 10.14.4
解決方法
reduxとreact-router-domのみを利用するとhistoryが利用できないので、reduxとreact-routerの統合が必要となる。
上記を実現するためにConnected React Routerというライブラリをインストールする。
(react-router-reduxは現在、非推奨)
引用元/@nacam403さんの記事
実装の流れ
- まず、npmで上記のライブラリを全てインストールします。
npm install --save redux
npm install --save react-router-dom
npm install --save connected-react-router
npm install --save redux-thunk
- index.jsを実装します。
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware } from 'redux'
import { createBrowserHistory } from "history"
import { routerMiddleware, ConnectedRouter } from 'connected-react-router'
import thunk from "redux-thunk"
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import rootReducers from './reducers'
const history = createBrowserHistory()
const store = createStore(
rootReducers(history),
applyMiddleware(
thunk,
routerMiddleware(history),
)
)
ReactDOM.render(<App store={store} history={history} />, document.getElementById('root'));
serviceWorker.unregister();
- App.jsを実装します。
AddFormでデータを登録して、CharacterListで一覧を表示する、というシンプルな構成です。
App.js
import React, {Component} from 'react'
import {Switch, Route} from 'react-router-dom'
import { Provider } from "react-redux"
import { ConnectedRouter } from 'connected-react-router'
import AddForm from './crud_components/AddForm'
import CharacterList from './crud_components/CharacterList'
class App extends Component {
render() {
return (
<Provider store={this.props.store}>
<ConnectedRouter history={this.props.history}>
<Switch>
<React.Fragment>
<div className="App">
<div className="container">
<Route exact path="/addform" render={() => <AddForm store={this.props.store} history={this.props.history}/>}/>
<Route exact path="/characterlist" render={() => <CharacterList store={this.props.store}/>}/>
</div>
</div>
</React.Fragment>
</Switch>
</ConnectedRouter>
</Provider>
);
}
}
export default App;
- AddForm.jsを実装します。
データ登録時のメソッドのみ抜粋します。ここでリダイレクトしたいpathをhistoryにpushします。
AddForm.js
onSubmit(e){
e.preventDefault() // フォームsubmit時のデフォルトの動作を抑制
const newCharacter = {
name: this.state.name,
age: this.state.age
}
const store = this.props.store;
character(newCharacter).then(res => {
if (res) {
this.props.history.push('/characterlist')
store.dispatch(initializeForm()) // submit後はフォームを初期化
}
})
}
まとめ
これでhistoryが利用できるようになりました。
しかし、historyでリダイレクトする際にstoreのデータを引き継ぎできないという課題が残るため、引き続き調べていきます。