我应该在调度时捕获 Redux promise 错误还是只在 reducer 中处理它?
Should I catch Redux promise errors at dispatch or just handle it in the reducer?
所以基本上我是用 thunk 和 redux-promise-middleware 调度一个动作,这使得 API 调用 returns 一个承诺。然后我将返回的承诺作为 'payload' 参数发送给另一个动作创建者,它与 redux-promise-middleware 一起工作并处理不同的动作 MY_ACTION_TYPE_PENDING 或 MY_ACTION_TYPE_REJECTED 或 MY_ACTION_TYPE_FULFILLED。我的问题是我是否通过 _REJECTED 操作处理 reducer 中的错误而不是在我的 dispatch(actionCreator(payload)? _REJECTED ACTION 错误。
以下是我的一些操作:
export const RECEIVE_POSTS = 'RECEIVE_POSTS';
export const receivePosts = (data) => ({
type: RECEIVE_POSTS,
payload: data
})
// thunk middleware for fetching blog
export const fetchPosts = () => {
return (dispatch) => {
const payload = contentfulClient.getEntries().then(
data => data.items,
error => console.log('An error occurred in fetchPost thunk middleware', error)
)
return dispatch(receivePosts(payload))
.catch((error) => {
console.log('caught error in fetchPost', error)
})
}
}
然后这是我的一些博客 reducer 文件,它处理 promise 中间件发出的操作
const status = (state = Status.IDLE, action) => {
switch (action.type) {
case `${RECEIVE_POSTS}_PENDING` :
return Status.PENDING;
case `${RECEIVE_POSTS}_FULFILLED`:
return Status.FULFILLED;
case `${RECEIVE_POSTS}_REJECTED`:
return Status.REJECTED;
default:
return state
}
}
const error = (state = null, action) => {
switch (action.type) {
case `${RECEIVE_POSTS}_REJECTED`:
return action.payload.message
default:
return state;
}
}
这是一个很好的问题,我认为没有唯一的答案。最终,这取决于开发人员或开发团队。作为一种实践,我会争辩说,是的,承诺错误应该在调度时 handled/caught 。这就是为什么...
在您的示例中,您没有捕捉到承诺错误。正如您所解释的,您只处理减速器中的错误。
case `${RECEIVE_POSTS}_REJECTED`:
return Status.REJECTED;
您读取类型为 ${RECEIVE_POSTS}_REJECTED
的对象并将更改写入状态。当您对状态进行更改时,您(大概更新 UI and/or 调度副作用来处理错误。这是 Redux 的典型实现。
但是,实际的承诺在此实现中仍未实现。为了捕获承诺错误,您需要在调度时这样做(或 in a middleware)。
dispatch(myAsyncActionCreator()).catch(function(error) {
// do something with the error
})
如果您在调度时发现错误,您将不会在控制台中看到错误。冗长,但 straightforward/explicit,这种做法使其他开发人员清楚如何处理错误。我相信清晰度对于可维护性和未来的变化很重要,因此我主张在调度时捕获错误。
希望对您有所帮助!
与 redux-promise-middleware
自动类型修改相比,我发现遵循 redux-thunk
代码更容易推理......因此作为替代发布,以防其他人发现比较也有用:
export const fetchPosts = () => (dispatch) => {
dispatch({type: '${RECEIVE_POSTS}_PENDING'})
contentfulClient.getEntries()
.then(data => dispatch({type: '${RECEIVE_POSTS}_FULFILLED', payload: data.items})
.catch(error => dispatch({type: '${RECEIVE_POSTS}_REJECTED', payload: error})})
}
所以基本上我是用 thunk 和 redux-promise-middleware 调度一个动作,这使得 API 调用 returns 一个承诺。然后我将返回的承诺作为 'payload' 参数发送给另一个动作创建者,它与 redux-promise-middleware 一起工作并处理不同的动作 MY_ACTION_TYPE_PENDING 或 MY_ACTION_TYPE_REJECTED 或 MY_ACTION_TYPE_FULFILLED。我的问题是我是否通过 _REJECTED 操作处理 reducer 中的错误而不是在我的 dispatch(actionCreator(payload)? _REJECTED ACTION 错误。
以下是我的一些操作:
export const RECEIVE_POSTS = 'RECEIVE_POSTS';
export const receivePosts = (data) => ({
type: RECEIVE_POSTS,
payload: data
})
// thunk middleware for fetching blog
export const fetchPosts = () => {
return (dispatch) => {
const payload = contentfulClient.getEntries().then(
data => data.items,
error => console.log('An error occurred in fetchPost thunk middleware', error)
)
return dispatch(receivePosts(payload))
.catch((error) => {
console.log('caught error in fetchPost', error)
})
}
}
然后这是我的一些博客 reducer 文件,它处理 promise 中间件发出的操作
const status = (state = Status.IDLE, action) => {
switch (action.type) {
case `${RECEIVE_POSTS}_PENDING` :
return Status.PENDING;
case `${RECEIVE_POSTS}_FULFILLED`:
return Status.FULFILLED;
case `${RECEIVE_POSTS}_REJECTED`:
return Status.REJECTED;
default:
return state
}
}
const error = (state = null, action) => {
switch (action.type) {
case `${RECEIVE_POSTS}_REJECTED`:
return action.payload.message
default:
return state;
}
}
这是一个很好的问题,我认为没有唯一的答案。最终,这取决于开发人员或开发团队。作为一种实践,我会争辩说,是的,承诺错误应该在调度时 handled/caught 。这就是为什么...
在您的示例中,您没有捕捉到承诺错误。正如您所解释的,您只处理减速器中的错误。
case `${RECEIVE_POSTS}_REJECTED`:
return Status.REJECTED;
您读取类型为 ${RECEIVE_POSTS}_REJECTED
的对象并将更改写入状态。当您对状态进行更改时,您(大概更新 UI and/or 调度副作用来处理错误。这是 Redux 的典型实现。
但是,实际的承诺在此实现中仍未实现。为了捕获承诺错误,您需要在调度时这样做(或 in a middleware)。
dispatch(myAsyncActionCreator()).catch(function(error) {
// do something with the error
})
如果您在调度时发现错误,您将不会在控制台中看到错误。冗长,但 straightforward/explicit,这种做法使其他开发人员清楚如何处理错误。我相信清晰度对于可维护性和未来的变化很重要,因此我主张在调度时捕获错误。
希望对您有所帮助!
与 redux-promise-middleware
自动类型修改相比,我发现遵循 redux-thunk
代码更容易推理......因此作为替代发布,以防其他人发现比较也有用:
export const fetchPosts = () => (dispatch) => {
dispatch({type: '${RECEIVE_POSTS}_PENDING'})
contentfulClient.getEntries()
.then(data => dispatch({type: '${RECEIVE_POSTS}_FULFILLED', payload: data.items})
.catch(error => dispatch({type: '${RECEIVE_POSTS}_REJECTED', payload: error})})
}