我应该在分发时捕获Redux Promise错误还是仅在reducer中处理它?

时间:2018-08-09 06:43:27

标签: javascript reactjs redux es6-promise redux-promise-middleware

因此,基本上,我正在使用thunk和redux-promise-middleware调度操作,该操作会进行API调用并返回承诺。然后,我将作为“有效负载”参数返回的承诺发送给另一个动作创建者,该参数与redux-promise-middleware一起使用,并处理不同的动作MY_ACTION_TYPE_PENDING或MY_ACTION_TYPE_REJECTED或MY_ACTION_TYPE_FULFILLED。我的问题是我是否通过_REJECTED操作处理减速器中的错误,而不在我的dispatch(actionCreator(payload)上捕获它?当我的调度程序中未捕获到错误时,尽管我的减速器在处理_REJECTED ACTION错误。

下面是我的一些动作:

EclipseLink

然后这是我的Blog Reducer文件中的一部分,它处理承诺中间件发出的动作

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

2 个答案:

答案 0 :(得分:1)

这是一个很好的问题,我认为没有答案。最终,这取决于开发人员或开发团队。作为一种实践,我会说,是的,保证应在发运时处理/发现错误。这就是为什么...

在您的示例中,您没有捕获到Promise错误。正如您所解释的,您只能处理减速器中的错误。

case `${RECEIVE_POSTS}_REJECTED`:
            return Status.REJECTED;

您读取了类型为${RECEIVE_POSTS}_REJECTED的对象,并将更改写入状态。当您将更改写入状态时,您(大概会更新UI和/或调度副作用以处理错误。这是Redux的典型实现。

但是,实际的承诺在此实现中仍然没有得到实现。为了捕获promise错误,您需要在分派(或in a middleware)处这样做。

dispatch(myAsyncActionCreator()).catch(function(error) {
  // do something with the error
})

如果在分发时发现错误,则在控制台中不会看到错误。详细但又简单明了的做法使其他开发人员清楚如何处理错误。我认为明确性对于可维护性和将来的变化很重要,因此,为什么我主张在派遣时发现错误。

希望有帮助!

答案 1 :(得分:1)

redux-thunk自动魔术类型修改相比,我发现更容易推理出遵循redux-promise-middleware代码的情况...因此,如果其他人也觉得比较有用,则可以发布该替代方法:

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