在我的项目中,我使用剩馀形式。
我想验证密码和自动登录用户到系统,如果密码是正确的。在用户被记录之后,我更新了一些内部的redux状态。为了做到这一点,我使用了redux thunk with action方法。
我面临的问题是redux thunk操作无法返回异步redux表单验证所需的承诺。
这是我的错误:
asyncValidate function passed to reduxForm must return a promise有人知道问题出在哪里吗?
下面是我使用的代码:
asyncValidate.js
import {logIn} from '../user/actions';
const asyncValidate = (values, dispatch) => {
return logIn(values.booker.email, values.booker.password);
}
export default asyncValidate用户登录操作
export const logIn = (email, password) => (dispatch) =>
new Promise(function (resolve, reject) {
axios.post('/login_check', qs.stringify({
_username: email,
_password: password,
_csrf_token: CSRF_TOKEN
}), ajaxConfig)
.then(response => {
if (response.data.success !== true) {
dispatch({
type: LOG_IN_ERROR,
payload: response.data.message
});
reject(response.data.message);
}
else {
dispatch({
type: LOG_IN_SUCCESS,
payload: response.data.user
});
resolve();
}
})
.catch((error) => {
dispatch({
type: LOG_IN_ERROR,
payload: error
});
reject(error);
})
});编辑1:
尝试了@Ravindra Ranwala建议的代码,但我仍然得到了相同的错误:
@Emrys Myrooin建议将代码从操作转移到asyncValidation函数,但当用户(在本例中是me)输入错误密码时,Redux-Form不会触发任何错误。
下面是新asyncValidate函数的代码:
import {LOG_IN_ERROR, LOG_IN_SUCCESS, CSRF_TOKEN} from '../booker/actions';
import axios from 'axios';
const qs = require('qs');
const ajaxConfig = {
headers: {"X-Requested-With": "XMLHttpRequest"}
};
const asyncValidate = (values, dispatch) => {
console.log(values);
return new Promise(function (resolve, reject) {
axios.post('/login_check', qs.stringify({
_username: values.booker.email,
_password: values.booker.password,
_csrf_token: CSRF_TOKEN
}), ajaxConfig)
.then(response => {
console.log(response);
if (response.data.success !== true) {
dispatch({
type: LOG_IN_ERROR,
payload: response.data.message
});
reject(response.data.message);
}
else {
dispatch({
type: LOG_IN_SUCCESS,
payload: response.data.user
});
resolve();
}
})
.catch((error) => {
dispatch({
type: LOG_IN_ERROR,
payload: error
});
reject(error);
})
})
}
export default asyncValidate编辑2.注释中的更新代码
使用此代码,一旦密码字段触发模糊事件,我就得到了以下错误:
Uncaught Error: asyncValidate function passed to reduxForm must return a promise在ajax请求完成后,我从一开始就得到了我想要的验证错误消息,但是密码字段没有被验证。
这是ajax请求完成后的错误:
asyncValidate.js?9b4c:19 Uncaught (in promise) Error: Bad credentials.asyncValidate函数:
import {logInError, logInSuccess, CSRF_TOKEN} from '../booker/actions';
import axios from 'axios'
const qs = require('qs')
const ajaxConfig = {
headers: { 'X-Requested-With': 'XMLHttpRequest' },
}
const asyncValidate = (values, dispatch) => {
axios
.post(
'/login_check', qs.stringify({
_username: values.booker.email,
_password: values.booker.password,
_csrf_token: CSRF_TOKEN,
}), ajaxConfig)
.then(response => {
console.log(response);
if (response.data.success)
dispatch(logInSuccess(response.data.user))
else
throw new Error(response.data.message)
})
.catch(error => {
dispatch(logInError(error.message))
throw error
})
}
export default asyncValidate减速器行动:
export const logInSuccess = response => ({
type: LOG_IN_SUCCESS,
payload: response
});
export const logInError = (response) => ({
type: LOG_IN_ERROR,
payload: response
});发布于 2017-08-03 08:23:39
您的函数logIn是一个返回动作的动作创建者,在这里是一个雷鸣般的动作。所以不,logIn的回归并不是一个承诺。
我认为您应该将异步代码移到asyncValidate函数中,并使用给定的dispatch参数来分派要修改redux状态的操作。
编辑
您的代码应该如下所示:
import { logInError, logInSuccess, CSRF_TOKEN } from '../booker/actions'
import axios from 'axios'
const qs = require('qs')
const ajaxConfig = {
headers: { 'X-Requested-With': 'XMLHttpRequest' },
}
const asyncValidate = (values, dispatch) =>
axios
.post(
'/login_check', qs.stringify({
_username: values.booker.email,
_password: values.booker.password,
_csrf_token: CSRF_TOKEN,
}), ajaxConfig)
.then(response => {
if (response.data.success)
dispatch(logInSuccess(response.data.user))
else
throw new Error(response.data.message)
})
.catch(error => {
dispatch(logInError(error.message))
throw { password: error.message })
})在你的文件中你应该有../booker/actions
export const logInSuccess = user => ({
type: LOG_IN_ERROR,
payload: user
})
export const logInError = (message) => ({
type: LOG_IN_ERROR,
payload: message
})一些解释:
正如另一个答案所指出的,您不必将ajax调用封装到Promise中,因为axios已经返回了一个承诺。若要拒绝then函数中的承诺,只需抛出一个错误。
另一个要点是从您定义操作的特定action文件中构建一个操作。否则,您将有大量重复的行动,这是可怕的维护。
最后一点,您可能永远不必在条件下显式地检查aBoolean === true。做if(aBoolean) ou if(!aBoolean)就行了。如果您还想检查您的变量实际上是布尔值(同样是非常不寻常的),则可以使用===。
发布于 2017-08-03 08:32:19
你不需要明确地回报承诺。当您将一个操作发送到商店时,thunk变得非常有用。试着像这样修改代码。
export function login(email, password) {
return function(dispatch) {
axios.post('/login_check', qs.stringify({
_username: email,
_password: password,
_csrf_token: CSRF_TOKEN
}), ajaxConfig)
.then(response => {
if (response.data.success !== true) {
dispatch({
type: LOG_IN_ERROR,
payload: response.data.message
});
}
else {
dispatch({
type: LOG_IN_SUCCESS,
payload: response.data.user
});
}
})
.catch((error) => {
dispatch({
type: LOG_IN_ERROR,
payload: error
});
})
}
}https://stackoverflow.com/questions/45478471
复制相似问题