2017-08-03 63 views
0

爲我的項目我正在使用Redux-Form異步驗證使用還原thunk

如果密碼正確,我想驗證密碼並自動將用戶登錄到系統。用戶登錄後,我更新了一些內部的重複狀態。要做到這一點,我使用了與操作方法的redux thunk。

我面臨的問題是,redux thunk操作無法返回async 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功能,但終極版表格移動代碼不會觸發任何錯誤,當用戶(我在這種情況下)輸入錯誤的密碼。

這裏是新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.評論

有了這個代碼,更新代碼,只要密碼字段觸發blur事件,我得到這個錯誤:

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 


}); 

回答

0

你的功能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 
}) 

幾點說明:

正如指出的oth呃回答,你不必把你的ajax調用封裝成Promise,因爲axios已經返回一個承諾。要拒絕then函數中的承諾,您可以合理地拋出錯誤。

另一個問題是,在你定義你的動作的特定文件action之外建立一個動作。否則,你將有噸重複的行動,這對維護是很糟糕的。

最後一點,您可能永遠不必在條件中明確檢查aBoolean === true。只要做if(aBoolean)if(!aBoolean)。如果你真的想檢查你的變量實際上是一個布爾值(也是非常不尋常的),那麼可以使用===

+0

我將logIn函數移到了asyncValidate函數,但由於某種原因驗證沒有觸發。 Ajax調用執行但沒有驗證錯誤(我輸入了錯誤的密碼) – jureispro

+0

使用您的代碼更新:-) –

+0

根據您的要求更新了代碼。 – jureispro

0

您不必顯式返回承諾。當您向商店發送操作時,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 
      }); 
     }) 
    } 
} 
+0

嗨。我試過你的代碼,同樣的錯誤仍然存​​在。問題是異步函數不會「等待」axios調用完成 – jureispro

+0

什麼是您的異步​​函數? –

+0

你可以在我的文章中的原始asyncValidate.js中看到它。我將logIn函數導入asyncValidate函數,並從那裏調用函數。 – jureispro