【问题标题】:reduxForm not submitting , gives error Unhandled Rejection (SubmissionError): Submit Validation FailedreduxForm 未提交,给出错误 Unhandled Rejection (SubmissionError): Submit Validation Failed
【发布时间】:2018-10-26 09:59:26
【问题描述】:

我正在使用reduxForm 7.4.2,我想提交表单并显示服务器端验证错误,但它给了我以下错误:

服务器响应:

这里是 LoginForm 组件:

import React,{Component} from 'react'
import InputGroup from '../ui/InputGroup';
import { bindActionCreators } from "redux"
import { Field , reduxForm,SubmissionError} from 'redux-form';
import {faEnvelope,faLock} from '@fortawesome/free-solid-svg-icons'
import { connect } from 'react-redux';
import { loginUser,loginUserFailure,loginUserSuccess } from '../../actions/authActions';


class LoginForm extends Component {
    constructor(){
        super();
        this.submitLoginForm=this.submitLoginForm.bind(this);
    }

    submitLoginForm=values=>{         
       this.props.loginUser(values);      
    }

    render() {
    const { handleSubmit, submitting} = this.props;
    return(
        <form onSubmit={handleSubmit(this.submitLoginForm)}>
                    <Field component={InputGroup} type="email" placeholder="Email" id="email" name="email" icon={faEnvelope}></Field>
                    <Field component={InputGroup} type="password" placeholder="Password" id="password" name="password" icon={faLock}></Field>
                    <button type="submit" className="btn btn-success btn-block" disabled={submitting}>Login</button>
        </form>
    )
  }
}

const mapStateToProps = (state, ownProps) => ({
    user:state.user
})


 const mapDispatchToProps = (dispatch) => {
   return bindActionCreators({
    loginUser,
    loginUserFailure,
    loginUserSuccess,
    }, dispatch)
  }

LoginForm = connect(mapStateToProps,mapDispatchToProps)(LoginForm);
LoginForm = reduxForm({ form: 'loginForm'})(LoginForm);
export default LoginForm;

src/actions/authActions

import axios from 'axios';
import { SubmissionError} from 'redux-form';


export const LOGIN_USER = 'LOGIN_USER';
export const LOGIN_USER_SUCCESS = 'LOGIN_USER_SUCCESS';
export const LOGIN_USER_FAILURE = 'LOGIN_USER_FAILURE';

export const loginUser =userdata=>{
   return dispatch => {
    try {
      const request = axios.post("/api/auth/login", userdata);
      request
        .then(res => {
          dispatch(loginUserSuccess(request));
        })
        .catch(e => {
          //dispatch(loginUserFailure(e));
          dispatch(loginUserFailure(e.response.data));
          throw new SubmissionError(e.response.data);
        });
    } catch (e) {
      dispatch(loginUserFailure(e));
    }
  }; 
 }

export const loginUserSuccess=user=>{
    return {
        type:LOGIN_USER_SUCCESS,
        payload:user
    }
}

export const loginUserFailure=error=>{
    return {
        type:LOGIN_USER_FAILURE,
        payload:error
    }
}

src/reducers/authReducer.js:

import { LOGIN_USER,LOGIN_USER_SUCCESS,LOGIN_USER_FAILURE} from './../actions/authActions';

const INITIAL_STATE = {isAuthenticated: false,user: null, status:null, error:null, loading: false};

  export default function(state = INITIAL_STATE, action) {
    let error;
    switch (action.type) {
        case LOGIN_USER:
        return { ...state, isAuthenticated: false,user: null, status:'login', error:null, loading: true}; 

        case LOGIN_USER_SUCCESS:
        return { ...state, isAuthenticated: true,user: action.payload.user, status:'authenticated', error:null, loading: false}; 

        case LOGIN_USER_FAILURE:
        error = action.payload.data || {message: action.payload.message};     
        return { ...state,isAuthenticated: false, user:null, status:'login', error:error, loading: false};

  default:
        return state;
    }
}; 

store.js

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const initialState = {};
const middleware = [thunk];

const store = createStore(
  rootReducer,
  initialState,
  compose(
    applyMiddleware(...middleware),
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
  )
);
export default store;

根减速器

import { combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form'
import authReducer from './authReducer';

export default combineReducers({
    form: formReducer,
    auth:authReducer
});

【问题讨论】:

    标签: reactjs redux react-redux redux-form react-redux-form


    【解决方案1】:

    这里有两件事你做错了。也许我错过了其他问题,但我确信这两个:

    在调度中绑定你的动作创建者,以便能够在哑组件抽屉中调度动作。这样做(只更改了部分,我正在编辑):

    import { bindActionCreators } from "redux"
    const mapDispatchToProps = (dispatch) => {
      return bindActionCreators({
        loginUser,
        loginUserFailure,
        loginUserSuccess,
      }, dispatch)
    }
    

    您必须使用 redux-thunk 作为中间件。它用于在使用 redux 和 react 时处理异步调度。你的 api 调用是异步的,所以在进行 axios post 调用后不能直接返回响应。你需要在那里返回一个函数,这样:

    export const loginUser = userdata => {
          return dispatch => {
            try {
              const request = axios.post("/api/auth/login", userdata);
              return request
                .then(res => {
                  dispatch(loginUserSuccess(request));
                })
                .catch(e => {
                  dispatch(loginUserFailure(e));
                });
            } catch (e) {
              dispatch(loginUserFailure(e));
            }
          };
        };
    

    并删除哑组件中的承诺处理。因为你所有的数据现在都在 redux 中可用了,你可以通过 mapStateToProps 获取。

    注意:我可能没有处理大括号。请检查并欢迎反馈

    【讨论】:

    • 有错误,请检查问题,我在下面添加了错误
    • 是的,正如我所说,您需要删除 .then 和 .catch 块,因为它现在仅在动作创建器中处理。如果您需要任何登录 api 数据,您应该通过 mapStatetoProps 获取。现在 loginUser 的返回不是一个承诺,而是它从来都不是一个承诺,即使在你的旧实现中也是如此
    • submitLoginForm=(values)=&gt;{return this.props.loginUser(values); } 这将给出错误TypeError: dispatch is not a function
    • 我现在该怎么办?我陷入了这个错误:(
    • 你在使用 redux-thunk 作为中间件吗?
    猜你喜欢
    • 1970-01-01
    • 2023-02-15
    • 2018-06-19
    • 2021-11-24
    • 1970-01-01
    • 2020-04-18
    • 1970-01-01
    • 2019-04-04
    • 2018-10-14
    相关资源
    最近更新 更多