React-axios-middleware 承诺处理

nob*_*ody 5 reactjs react-native react-redux axios

我正在开发一个用于redux-axios-middleware执行 XHR 请求的 React 应用程序。它的设置方式与客户端类似,如下所示index.js

const client = axios.create({ //all axios can be used, shown in axios documentation
  baseURL:'https://api.vktest.xxx/api',
  responseType: 'json',
  validateStatus: function (status) {
    return status >= 200 && status < 300
  }
});

const axiosMiddle = axiosMiddleware(client)

export const store = createStore(rootReducer, composeEnhancers(applyMiddleware(thunk, axiosMiddle)))
Run Code Online (Sandbox Code Playgroud)

然后,我从我的组件中调用我的操作,如下所示:

store.dispatch(loginAction(credentials))

这是动作:

import { LOGIN } from './types'

export function loginAction(credentials) {

  return dispatch => {
      return dispatch(doLogin(credentials) ).then(
      response => {
        dispatch({type: 'LOGIN_SUCCESS', response})
      },
      error => {
        dispatch({type: 'LOGIN_FAIL', error})
        throw error
      }
    )
  }
}

function doLogin(credentials) {
  return {
    type: LOGIN,
    payload: {
      request: {
        url: '/login/',
        method: 'POST',
        data: {
          username: credentials.username,
          password: credentials.password
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

它调度由 axios-middleware 捕获的 doLogin 函数来执行 XHR 调用。调用后,axios Promise 包含类型LOGIN_SUCCESSLOGIN_FAIL。Axios 自动调度这些类型,reducers 可以对它们进行操作。到目前为止,一切都很好。

但是(我试图尽可能清楚),当 axios 请求失败时,axios Promise 被拒绝并LOGIN_FAIL分派类型。由于该承诺已得到解决,该.then(..).catch(..)块始终会调用.then. 我似乎无法在处理调度回调而.then不是 axios 回调的块中做一些丑陋的事情来处理 axios 错误。

为了澄清以下情况正在发生:

store.dispatch -> action -> doLogin -> axios -> reducer -> back to action dispatch.

我想处理 axios 和 reducer 步骤之间的 XHR 错误,但是当我这样做时:

import { LOGIN } from './types'

export function loginAction(credentials) {

  return dispatch => {
      return dispatch(doLogin(credentials).then(
      response => {
        dispatch({type: 'LOGIN_SUCCESS', response})
      },
      error => {
        dispatch({type: 'LOGIN_FAIL', error})
        throw error
      }
    ))
  }
}

function doLogin(credentials) {
  return {
    type: LOGIN,
    payload: {
      request: {
        url: '/login/',
        method: 'POST',
        data: {
          username: credentials.username,
          password: credentials.password
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

Uncaught TypeError: doLogin(...).then is not a function
    at authentication.js:6
Run Code Online (Sandbox Code Playgroud)

我想解决这个问题的原因是因为当前的设置调度以下内容:

电流

如图所示,LOGIN_FAIL(axios) 和LOGIN_SUCCESS(dispatch) 都被调用。我希望能够自己处理 axios 错误,因为我希望能够向用户提供登录尝试失败的反馈。不知何故,我无法弄清楚如何。

有人能帮我吗?

Tom*_*zyk 3

我想我知道你的意思。

您可以通过在中间件配置中设置returnRejectedPromiseOnError来更改该行为。

请注意,承诺仅返回到链式操作。如果您设置此选项,您将必须始终应用catch回调,否则您将收到unhandled rejection when calling Promise错误。在组件中处理时,这可能会导致一些问题,因为当组件已经卸载时可能会触发这些回调。

在我的代码中,我尝试then尽可能避免避免这些副作用,但当我必须这样做时,我会这样做:

fetchSomething.then(action => {
  if(action.type.endsWith('SUCCESS')) {
      ....
  }

})
Run Code Online (Sandbox Code Playgroud)