如何在单个Epic中分发两个Action(含跨Reducer场景)
问题解决:单个Epic触发跨Duck的多个Action
问题根源分析
你的代码存在两个关键问题:
- Action流被覆盖:switchMap返回的UI Action被后续的
map操作转换成了Backend的ENDACTION,导致UI Action从未被分发到Store,仅执行了Action创建函数里的日志。 - 请求结果处理错误:直接访问
response.props时,response是Observable对象而非请求返回的数据,导致UI Action的payload无效。
修正后的Backend Duck Epic代码
fetchFooEpic: (action$, store) => action$.pipe( operators.filter(action => action.type === types.LOAD), operators.switchMap(action => // 发起请求,获取返回数据 operators.from(fetchSomeUrl(action)).pipe( // 请求成功后,同时发射两个Action operators.mergeMap(responseData => rxjs.of( // Backend自身的Action { type: types.ENDACTION, payload: responseData.payload }, // UI Duck的Action uiDuck.actions.fetchUserFulfilled(responseData.props) ) ), // 内部错误处理,避免整个Epic终止 operators.catchError(err => { console.error('Error happened!', err.message); return rxjs.of({ type: types.ADD_CATEGORY_ERROR, payload: err }); }) ) ) )
关键修正点说明
- 合并多个Action:使用
mergeMap(若需严格顺序触发可换concatMap)包裹rxjs.of,一次性发射两个Action,确保它们都能被分发到Store。 - 正确获取请求数据:
fetchSomeUrl返回的Promise解析后的数据会传入mergeMap,此时responseData是真实的请求结果,可正常访问responseData.props。 - 错误处理内移:将
catchError放在请求的Observable流内部,单个请求失败不会导致整个Epic停止监听后续的LOAD动作。
验证要点
- 确认
fetchSomeUrl(action)返回的响应数据确实包含props和payload字段。 - 检查UI Duck中
types.FETCHUSERFULFILLED常量与Reducer的case值完全一致(注意大小写、拼写)。
内容的提问来源于stack exchange,提问作者til
相关产品推荐
相关产品推荐

