reactjs - 是否可以在 Redux Action 中提前返回

标签 reactjs react-redux axios

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

背景信息
有一个使用 Laravel 的后端 API。在这段代码中,我登录 API 以使用 React-Redux 获取 JWT token 。以后调用API时需要这个token。该代码运行完美,并且在实际成功时收到 token ,但我无法在失败时提前返回。

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'
    }
}

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

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

如果 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'
        });
    }

最佳答案

如果失败,您的应用程序流程如下所示:

  1. post promise 得到解决之前返回 FETCH_API_TOKEN_SUCCESS
  2. 网络调用失败,promise被拒绝并且catch block 被执行
  3. JS 引擎处理 catch block 语句并返回具有 FETCH_API_TOKEN_FAILURE 操作类型的新 Promise

我建议您对网络调用使用三态方法,例如PENDING、SUCCESS 和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用于处理 reducer 中的 promise 的中间件。

附注您正在返回带有 token: request 字段的 FETCH_API_TOKEN_SUCCESS 操作。在这种情况下,request 是一个 promise ,我假设您在进一步的代码中正确处理了这个问题。

P.S.S 很可能你的catch block 不会返回任何东西,因为catch中的return语句将被包装到promise中,你需要通过then或来解决它捕获

关于reactjs - 是否可以在 Redux Action 中提前返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44264502/

相关文章:

laravel - 为什么我的下载功能(使用 Vue JS 和 Laravel 创建)会导致文件损坏?

javascript - 按属性对数组排序

javascript - React JS 从另一个位置导入/需要文件/页面

performance - React Redux 中 `Provider` 和 `connect` 之间的区别

reactjs - React 路由器更改 url 但不更改 View (仅在 Internet Explorer 11 上)

javascript - 如何使用 redux 获取更新后的状态

javascript - 忽略 react 路由器路由

javascript - Redux - Hooks : Using React Hooks with Redux Hooks, 创建无限循环或根本不创建任何内容

reactjs - 在 axios 拦截器错误的情况下如何重新调用 API

javascript - axios get 请求无法将 undefined 转换为对象