如何在Epic的Action回调中调度Action?问题求助
解决Toast Undo回调中Action无法触发的Epic层面方案
问题场景
我在基于Redux-Observable实现makeXDiningReservation功能时遇到了卡点:当showWarnToastMessage的onUndo回调触发后,回调内返回的Action完全无法被调度执行。原本直接在onUndo里返回Action数组的写法完全无效。
解决方案
要从Epic层面解决这个问题,不能直接在Toast的回调里返回Action,而是需要通过触发专门的Undo Action,再用独立Epic监听这个Action来执行后续逻辑。具体步骤如下:
- 定义专属的Undo Action类型及创建函数
- 修改
showWarnToastMessage的onUndo配置,改为触发这个新的Undo Action - 编写独立Epic监听该Undo Action,执行原本回调中的导航、模态框操作
修改后的代码实现
1. 新增Undo Action定义
// 定义Undo Action类型 export const DINING_RESERVATION_UNDO = "DINING_RESERVATION_UNDO"; // 对应Action创建函数 export const diningReservationUndo = (data) => ({ type: DINING_RESERVATION_UNDO, payload: data, });
2. 调整原Epic中的Toast配置
export const makeXDiningReservation = createDataEpic({ name: "makeXDiningReservation", apiPath: (action, state) => generatePath("pathToApi", { }), apiOptions: (action, state) => { return { headers: { "Client-Id": "ship", "Content-Type": "application/json", }, body: JSON.stringify(data), }; }, successActionCreator: ( response, state, action, { getIntl, ...rest }, ...params ) => { if (isDailyPlannerEnabled && eventOverlap) { return [ Actions.throttledScheduleRefresh({ force: true }), Actions.diningReservationSuccessOnShip({ ...action, reservationID: response.bookingId, }), Actions.navigateReplace({ pathname: generatePath("path", { restaurantKey: action.restaurantKey, }), state: { action, response: { ...response, reservationID: response.bookingId }, }, }), Actions.showWarnToastMessage( getIntl(state).formatMessage( strings.activityOverlapsWithAnotherActivity, ), { color: "warning", variant: "standard", showUndo: true, undoData: response, // 替换原回调逻辑,改为触发专门的Undo Action onUndo: (data) => { store.dispatch(diningReservationUndo(data)); }, }, ), ]; } else { return [ Actions.diningReservationSuccessOnShip({ ...action, reservationID: response.bookingId, }), Actions.navigateReplace({ pathname: generatePath("/dining/:restaurantKey/confirm", { restaurantKey: action.restaurantKey, }), state: { action, response: { ...response, reservationID: response.bookingId }, }, }), ]; } }, failureActionCreator: (error, state, action) => [ Actions.epicError(makeXDiningReservation.name, error), stopSubmit(action.form, { _error: error }), ], triggeringActions: [START_DINING_RESERVATION], type: REQUEST_TYPE.POST_JSON, waitingIdentifier: "DINING_RESERVATION", });
3. 新增Undo逻辑专属Epic
export const diningReservationUndoEpic = (action$) => action$.pipe( ofType(DINING_RESERVATION_UNDO), mergeMap((action) => { const data = action.payload; return of( Actions.navigatePush({ pathname: generatePath("/dailyPlanner"), }), modalActivityActionDrawerActions.setModalState(true) ); }) );
最后注意事项
确保新增的diningReservationUndoEpic被注册到项目的Root Epic中,这样才能被Redux-Observable的中间件监听执行。
内容的提问来源于stack exchange,提问作者abhishek dana
相关产品推荐
相关产品推荐

