我正在使用一个使用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)))
从我的组件中,我就是这样调用我的动作:
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
}
}
}
}
}
它调度由axios-middleware捕获的doLogin函数来执行XHR调用。在调用之后,axios promise包含类型LOGIN_SUCCESS
或LOGIN_FAIL
。 Axios自动调度这些类型,减速器可以对它们进行操作。到现在为止还挺好。
然而(我试图尽可能清楚),当axios请求失败时,axios承诺被拒绝并调度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
}
}
}
}
}
我收到以下错误:
Uncaught TypeError: doLogin(...).then is not a function
at authentication.js:6
我想解决此问题的原因是因为当前设置会调度以下内容:
如图所示,正在调用LOGIN_FAIL
(axios)和LOGIN_SUCCESS
(调度)。我希望能够自己处理axios错误,因为我希望能够为用户提供失败登录尝试的反馈。不知怎的,我无法弄清楚如何。
有人可以帮助我吗?
答案 0 :(得分:3)
我想我知道你的意思。
您可以通过在中间件配置中设置returnRejectedPromiseOnError来更改该行为。
请注意,promise仅返回到链操作。如果您设置此选项,则必须始终应用catch
回调,否则您将收到unhandled rejection when calling Promise
错误。当在组件中处理时,这可能会导致一些问题,因为当组件已经卸载时可能会触发这些回调。
我的代码我尽量避免then
以避免这些副作用,但是当我不得不这样做时:
fetchSomething.then(action => {
if(action.type.endsWith('SUCCESS')) {
....
}
})