LoginSignup
5
3

More than 3 years have passed since last update.

historyオブジェクトについて

Posted at

課題

  • 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のデータを引き継ぎできないという課題が残るため、引き続き調べていきます。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3