[英]Async validation with redux-thunk
對於我的項目,我正在使用Redux-Form 。
我想驗證密碼,如果密碼正確,則自動將用戶登錄到系統。 用戶登錄后,我更新了一些內部的還原狀態。 為此,我使用了帶有動作方法的redux thunk。
我面臨的問題是redux thunk操作無法返回異步redux-form驗證所需的Promise。
這是我有的錯誤:
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函數,但當用戶(在本例中為我)輸入錯誤密碼時,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
});
您的函數logIn
是一個動作創建者,該動作創建者返回一個動作,此處為一個thunk。 所以不,返回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已經返回了promise。 要拒絕then
函數中的承諾,您可以拋出一個錯誤。
另一點是從定義動作的特定action
文件中構建動作。 否則,您將有大量重復的操作,並且維護起來很糟糕。
最后一點,您可能不必在條件中顯式檢查aBoolean === true
。 只需執行if(aBoolean)
或if(!aBoolean)
。 如果確實要檢查您的變量是否確實是布爾值(同樣非常不尋常),則可以使用===
。
您不必顯式地返回承諾。 當您將操作分派給商店時,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
});
})
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.