重定向成功提交表单

时间:2017-01-23 15:03:30

标签: reactjs redux react-router react-router-redux

我正在尝试为教育目的实现一个简单的表单逻辑。我很难尝试在表单提交时重定向到url。以下是我的代码的相关部分;

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';

import { createStore, combineReducers, applyMiddleware  } from 'redux'
import { Provider } from 'react-redux'
import { Router, Route, IndexRoute, hashHistory } from 'react-router'
import { syncHistoryWithStore, routerReducer, routerMiddleware } from 'react-router-redux'
import { reducer as formReducer } from 'redux-form'

import {Home, Foo, Bar} from './components'
import {YirtibatLoginForm as LoginForm} from './containers/LoginForm'

import * as reducers from './reducers'

const reducer = combineReducers({
        ...reducers,
    routing: routerReducer,
    form: formReducer
})

const middleware = routerMiddleware(hashHistory)

const store = createStore(reducer, applyMiddleware(middleware))
const history = syncHistoryWithStore(hashHistory, store)



ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
        <Route path="/" component={App}>
            <IndexRoute component={Home} />
            <Route path="foo" component={Foo} />
            <Route path="bar" component={Bar} />
            <Route path="login" component={LoginForm} />
        </Route>
    </Router>
  </Provider>,
  document.getElementById('root')
);

containers/LoginForm.js

import React, { Component } from 'react';

import { connect } from 'react-redux'
import { push } from 'react-router'

import LoginForm from '../components/LoginForm'

export class BaseYirtibatLoginForm extends Component {
    constructor() {
        super();

        this.handlesubmit = this.handlesubmit.bind(this);
    }

    handlesubmit(ev) {
        this.props.submitting();

        fetch('/login', {
            method:'POST',
            body:JSON.stringify(ev)
        }).then(resp => {
            if(!resp.ok) {
                throw new Error(resp.statusText)
            }
            return resp.json()
        }).then( resjson => {
            this.props.submitsuccess(resjson)
        }).catch(err => {
            this.props.submiterror(err);
        })
    }

    render() {
        return (
            <LoginForm onSubmit={this.handlesubmit} />
        );
    }
}

const mapStateToProps = (state) => {return {}}
const mapDispatchToProps = (dispatch) => {
    return {
        submitting: () => dispatch({type:'submitting'}),
        submitsuccess: (data) => push("/success"),
        submiterror: (err) => push("/error")
    }
}

export const YirtibatLoginForm = connect(mapStateToProps, mapDispatchToProps)(BaseYirtibatLoginForm);

我认为此代码应该在提交表单后重定向哈希URL。但是我在浏览器控制台中遇到以下错误;

Uncaught (in promise) TypeError: (0 , _reactRouter.push) is not a function
    at Object.submiterror (LoginForm.js:45)
    at LoginForm.js:29
submiterror @ LoginForm.js:45
(anonymous) @ LoginForm.js:29

在提交事件之后,重定向到路由组件的首选方法是什么?

1 个答案:

答案 0 :(得分:0)

push导出的react-router函数没有。您可以直接使用历史记录对象,如评论中所述,但最好的方法是使用withRouter higher-order component。下面的代码通过内联注释触及关键点。

// import
import { withRouter } from 'react-router'
...

export class BaseYirtibatLoginForm extends Component {
    ...
    handlesubmit(ev) {
        this.props.submitting();


        fetch('/login', ...
        ).then( resjson => {
            // take `router` from `this.props` and push new location
            this.props.router.push("/success")
        }).catch(err => {
            // take `router` from `this.props` and push new location
            this.props.router.push("/error")
        })
    }
}

const mapStateToProps = (state) => {return {}}
const mapDispatchToProps = (dispatch) => {
    return {
        submitting: () => dispatch({type:'submitting'}),
        // redirect is not done through redux actions
    }
}

// apply withRouter HoC
export const YirtibatLoginForm = withRouter(connect(mapStateToProps, mapDispatchToProps)(BaseYirtibatLoginForm));