如何在Redux Toolkit中复用同一个rejected错误处理逻辑?
在Redux Toolkit中复用rejected错误处理逻辑
现有代码
extraReducers: builder => { builder.addCase(getTopicsByDcResponsable.fulfilled, (state, action) => { if(action.payload.status === 200){ state.error = ''; state.userTopics.responsableTopics.push(...action.payload.data); } else { state.error = action.payload.data; } }); builder.addCase(getTopicsByDcResponsable.rejected, (state, action) => { state.error = action.payload; }); builder.addCase(getTopicsbyDcentroEdit.fulfilled, (state, action) => { if(action.payload.status === 200){ state.error = ''; state.userTopics.editorTopics.push(...action.payload.data); } else { state.error = action.payload.data; } }); builder.addCase(getTopicsbyDcentroEdit.rejected, (state, action) => { state.error = action.payload; }); },
问题背景
当前所有异步action的rejected分支处理逻辑完全一致,都是将state.error设置为action.payload,希望复用这部分逻辑,避免重复代码。
解决方案
方法1:提取公共错误处理函数
把重复的错误逻辑抽成独立函数,在每个addCase中直接引用,适合针对特定几个异步action复用逻辑:
// 提取公共rejected处理函数 const handleAsyncRejected = (state, action) => { state.error = action.payload; }; extraReducers: builder => { builder.addCase(getTopicsByDcResponsable.fulfilled, (state, action) => { if(action.payload.status === 200){ state.error = ''; state.userTopics.responsableTopics.push(...action.payload.data); } else { state.error = action.payload.data; } }) // 直接引用公共函数 .addCase(getTopicsByDcResponsable.rejected, handleAsyncRejected) .addCase(getTopicsbyDcentroEdit.fulfilled, (state, action) => { if(action.payload.status === 200){ state.error = ''; state.userTopics.editorTopics.push(...action.payload.data); } else { state.error = action.payload.data; } }) // 再次引用公共函数 .addCase(getTopicsbyDcentroEdit.rejected, handleAsyncRejected); },
方法2:使用builder.addMatcher全局匹配所有rejected action
Redux Toolkit通过createAsyncThunk生成的action类型,都会以/rejected结尾。利用addMatcher可以匹配所有符合该模式的action,实现全局统一处理:
extraReducers: builder => { builder.addCase(getTopicsByDcResponsable.fulfilled, (state, action) => { if(action.payload.status === 200){ state.error = ''; state.userTopics.responsableTopics.push(...action.payload.data); } else { state.error = action.payload.data; } }) .addCase(getTopicsbyDcentroEdit.fulfilled, (state, action) => { if(action.payload.status === 200){ state.error = ''; state.userTopics.editorTopics.push(...action.payload.data); } else { state.error = action.payload.data; } }) // 匹配所有createAsyncThunk生成的rejected action .addMatcher( action => action.type.endsWith('/rejected'), (state, action) => { state.error = action.payload; } ); },
两种方法对比
- 方法1灵活性更高,可选择性地给特定action绑定错误处理逻辑;
- 方法2更简洁,自动覆盖所有
createAsyncThunk生成的异步请求错误,适合全局统一错误处理场景。
内容的提问来源于stack exchange,提问作者ddaudiosolutions
相关产品推荐
相关产品推荐

