Redux 错误处理
这两天正好收尾一个 Redux 页面的重构,碰到了一些错误处理的方式,这里就写个笔记总结一下碰到的问题和几种处理方式
大体上是分为同步函数和异步函数两个方面去处理
同步函数
这个是指的是直接在 reducer 中进行操作,可以是 extraReducers
或者是 reducer
throw exception
user may interae with UI then trigger some error, in this case, the state may not need to be updated
我之前有用过这个,不过后面因为应用场景不太符合的关系修改了一部分操作,大致实现如下:
createSlice({
reducers: {
// 属于有使用场景的
someAction() {
throw new Error('some error');
},
},
// 这个用法其实不太好……
extraReducers(builder) {
builder.addCase(someAsyncAction.rejected, (state, action) => {
state.isLoading = false;
state.error = action.error;
throw new Error('state.error');
});
},
});
这种应用场景其实比较少,我能想到的大概就触发一些成功之前不会造成状态变化的应用案例需要使用异常的方式解决。
其中最大的一个问题就在于,一旦跑出异常后,它的状态更新就失败了,如 extraReducers
中的操作,如果只是为了抛异常的话,其实 redux 的状态不会有任何的变化。
这也是之后我决定使用其他的方式解决异步异常的问题,因为一旦 loading
的状态没有办法 toggle,就相当于整个页面卡在了 freeze 的状态
使用状态去管理
这个就是比较常规的处理方式了,依旧以上面的代码为例,在组件中我可以从状态中获取 isLoading
和 error
这两个状态。相对应的,我也可以在组件中通过对这两个状态进行检查而更新页面的渲染状态。
如 isLoading
的时候页面渲染旋转的符号,有 error
的时候页面弹出报错框等,这种都属于根据状态去管理页面的状态。
这个情况大概可以解决 70-80%的正常业务。
异步函数
这个主要是针对 asyncThunk
解决的问题,如果没有使用 asyncThunk
的话,可能还是要退回上一步去解决。
说一下碰到的业务场景:
基本上说,如果用户操作表单失败的情况下,表单的状态需要维持在一个 开启
的状态,同时因为整个页面会有多种类型的表单操作,因此单纯依靠 loading
和 error
的操作就变得非常的麻烦
我在 log 了一下 await asyncOps()
的操作后发现它的返回值是一个很好用的操作,如:
这里可以通过 meta
获取异步调用的状态,从而指导应该进行什么操作:
if (res.meta.requestStatus === 'fulfilled') {
// 如果需要更新其他关联数据
dispatch(someOtherCalls(somePayload));
closeModal();
}