是否有可能在Redux Action中提前返回

时间:2017-05-30 14:05:19

标签: reactjs react-redux axios

问题
我觉得这是一个范围问题。我无法返回catch区块。它总是回归成功。虽然if语句适用于失败部分(我使用console.log调试它)。

背景资料
有一个使用laravel的后端API。在这段代码中,我正在登录API以使用react-redux获取JWT令牌。将来需要此令牌来调用API。代码工作正常,并且在实际成功上接收令牌,但我无法在失败时提前返回。

export function requestApiToken(username, password){    
    const url = ROOT_URL + 'user/login';
    const request = axios.post(url, {
        email: username,
        password: password,
        headers: {
            'Content-Type': 'application/json',
            'X-Requested-With': 'XMLHttpRequest'
        }
    })
    .catch(function (error) {
        //somehow it always returns an error
        //currently 500=succes (will fix that later in api to 200)

        if(error.response.status == 500){
            console.log('succes')
            console.log(error.response.data);
        }else{
            console.log('error')
            console.log(error.response.data);
            return{
                type: FETCH_API_TOKEN_FAILURE,
                token: null,
                message: 'Please enter a valid e-mail and username for the API and try again'
            }
        }
    });

    return{
        type: FETCH_API_TOKEN_SUCCES,
        token: request, //should be error.response.data
        message: 'Succesfull login'
    }
}

编辑作为对评论部分的回复。
这是服务器返回的内容:

如果块成功(调试)
Succes if block

如果块失败(调试)
Failure if block

目前代码总是进入代码块返回FETCH_API_TOKEN_SUCCES

正如答案中所建议的那样,我使用redux-thunk作为我的中间件而不是redux-promise

在index.js中添加

import thunk from 'redux-thunk';
const createStoreWithmiddleware = applyMiddleware(thunk)(createStore);

在requestApiToken方法

return(dispatch) => {
        request.then(function (response) {
            dispatch({
                type: FETCH_API_TOKEN_SUCCESS,
                token: response.data.token,
                message: 'Successfull login'
            })
        });
        request.catch(function (error) {
            if(error.response.status == 422){
                dispatch({
                        type: FETCH_API_TOKEN_FAILURE,
                        token: null,
                        message: 'Please enter a valid e-mail and username for the DiabetesAPI and try again'
                })
            }
        });

        dispatch({
            type: FETCH_API_TOKEN_PENDING,
            token: null,
            message: 'Pending API Token request'
        });
    }

2 个答案:

答案 0 :(得分:1)

如果失败,您的申请流程如下:

  1. FETCH_API_TOKEN_SUCCESS承诺解决之前返回post
  2. 网络呼叫失败,承诺为rejectedcatch阻止执行
  3. JS引擎通过catch阻止语句并使用FETCH_API_TOKEN_FAILURE操作类型返回新的承诺
  4. 我建议您使用三态方法进行网络调用,例如PENDING, SUCCESS and FAILURE。在这种情况下,您可以显示加载器并准确知道网络呼叫何时结束。

    export function requestApiToken(username, password) {
        const url = ROOT_URL + 'user/login';
        const request = axios.post(url, {
            email: username,
            password: password,
            headers: {
                'Content-Type': 'application/json',
                'X-Requested-With': 'XMLHttpRequest'
            }
        })
        .then(function (response) {
            return {
                type: FETCH_API_TOKEN_SUCCESS,
                token: response.token,
                message: 'Successfull login'
            }
        })
        .catch(function (error) {
            return {
                type: FETCH_API_TOKEN_FAILURE,
                token: null,
                message: getErrorMessage(error.response.status)
            }
        });
    
        return Promise.resolve({
            type: FETCH_API_TOKEN_PENDING,
            token: null,
            message: 'Loading'
        });
    }
    
    function getErrorMessage(statusCode) {
        if (statusCode == 422) { 
            return 'Please enter a valid e-mail and username for the API and try again';
        } else {
            return 'Error has occurred';
        }
    }
    

    请注意,您需要在reducer中按then解析操作创建者的值,因为返回值为Promise

    正如其他人注意到的那样,你需要redux-thunk中间件来处理减速器中的承诺。

    P.S。您将使用FETCH_API_TOKEN_SUCCESS字段返回token: request操作。在这种情况下,request是一个承诺,我假设你在进一步的代码中正确处理了这个。

    P.S.S很可能你的catch块没有返回任何内容,因为catch中的return语句将被包含在promise中,你需要通过thencatch来解析它

答案 1 :(得分:1)

呃,您的代码存在很多问题。最好慢慢学习,并了解你尝试使用的每个概念是如何运作的。

Action creator是一个返回描述操作的普通对象的函数。

Axios是一个允许您向服务器发出请求的库。 Axios.post()将返回一个promise,它允许您使用then()和catch()方法处理请求的结果。这些方法采用回调函数,并且您已经正确地提供了一个catch()调用。问题是回调中的return语句从回调返回,而不是从动作创建者返回。您无法在操作创建者中进行异步API调用,然后从成功或失败回调中返回操作。

另一个问题是您在Axios.post()调用之后返回成功操作。这意味着动作创建者一旦发出呼叫就会返回成功动作,而不会等待它返回响应。

如果您想在您的动作创建者中进行API调用,请查看redux-thunk这是Redux中间件,它允许您从动作创建者返回承诺,这些承诺可以在解决或拒绝时发送自己的行为。< / p>