React,Immutable,fetch()-错误处理导致未定义的状态元素



我想我理解错误发生在哪里,但我能够为fetch()返回的Promise制定正确的处理流程

我的消息缩减器模块:-

import { fetchMessages } from '_helpers/api'
import { Map, fromJS } from 'immutable'
const FETCHING_MESSAGES = 'FETCHING_MESSAGES'
const FETCHING_MESSAGES_FAILURE = 'FETCHING_MESSAGES_FAILURE'
const FETCHING_MESSAGES_SUCCESS = 'FETCHING_MESSAGES_SUCCESS'
const ADD_MESSAGES = 'ADD_MESSAGES'
const ERROR_MESSAGE = 'There has been an error'
export const fetchAndHandleMessages = () => {
return (dispatch, getState) => {
dispatch(fetchingMessages())
fetchMessages()
.then((r) => {
if (!r.ok) {
dispatch(fetchingMessagesFailure(ERROR_MESSAGE))
}else{
return r.json()
}
})
.then((b) => {
dispatch(fetchingMessagesSuccess(b))
})
.catch(() => {
dispatch(fetchingMessagesFailure(ERROR_MESSAGE))
})
}
}
function fetchingMessagesSuccess(messages) {
return {
type: FETCHING_MESSAGES_SUCCESS,
messages,
lastUpdated: Date.now(),
}
}
function fetchingMessagesFailure(errMsg) {
return {
type: FETCHING_MESSAGES_FAILURE,
error: errMsg
}
}
const fetchingMessages = () => {
return {
type: FETCHING_MESSAGES,
}
}
const initialState = fromJS({
messages: [],
isFetching: true,
error: '',
})
export const messagesReducer = (state = initialState, action) => {
switch (action.type) {
case FETCHING_MESSAGES :
return state.merge({
isFetching: true,
})
case FETCHING_MESSAGES_SUCCESS :
return state.merge({
error: '',
isFetching: false,
messages: action.messages
})
case FETCHING_MESSAGES_FAILURE:
return state.merge({
error: action.error,
isFetching: false
})
default :
return state
}
}
export default messagesReducer

fetchMessage()只返回一个promise:-

export const fetchMessages = () => {
return fetch(baseUrl + 'messages')
}

我不会在这里发布组件代码,因为它与问题无关。

因此,如果我用无效的URL调用fetchMessage()来返回404,则state.messages在我的组件中会变成未定义。这似乎是由功能的这一部分引起的:-

if (!r.ok) {
dispatch(fetchingMessagesFailure(ERROR_MESSAGE))
}else{
return r.json()
}

我想我可能会对如何正确检查和处理返回的Promise中的潜在错误感到困惑。根据fetch()的文档,404不被认为是错误,因为(与常规AJAX不同)只有网络问题被认为是catch()类型的错误。

有人能帮我指出我代码的这一部分出了什么问题吗?我应该在调度(fetchingMessagesFailure(ERROR_MESSAGE))之后使用退出来停止下面的.then()catch()块也在运行。这似乎违背了医生的建议。

非常感谢您的帮助。谢谢

我看到您在!r.okcatch上使用相同的操作。。。所以我建议在!r.ok的情况下通过抛出错误来断链:

fetchMessages()
.then((r) => {
if (!r.ok) {
throw true; // just go to .catch()
}
return r.json()
})
.then((b) => dispatch(fetchingMessagesSuccess(b)))
.catch(() => dispatch(fetchingMessagesFailure(ERROR_MESSAGE)))

最新更新