如何在Redux Toolkit的action内部调用另一个action?
在Redux Toolkit中实现reset触发generateCard的几种方式
Redux的reducer是纯函数,不能在reducer内部直接调用另一个action creator,所以可以通过以下几种方式实现需求:
方案1:复用核心逻辑代码
把generateCard的业务逻辑抽成独立函数,在reset和generateCard的reducer里直接调用,既实现代码复用,又不需要额外触发action。
// 抽离可复用的卡片生成逻辑 const updateGridWithCard = (state, count) => { // 这里写你原本要在generateCard里实现的逻辑 // 比如查找网格空单元格、添加指定数量的卡片等 }; const scoreSlice = createSlice({ name: 'score', initialState, reducers: { addScore: ({ score }, action) => { score += action.payload; }, reset: (state) => { state.score = 0; state.grid = initialState.grid; // 直接调用卡片生成逻辑,传入数量2 updateGridWithCard(state, 2); }, generateCard: (state, action) => { updateGridWithCard(state, action.payload); }, }, });
方案2:将reset改为Thunk函数
如果必须通过触发generateCard action来实现,可以把reset封装成一个thunk函数,内部依次触发同步的重置action和卡片生成action。
const scoreSlice = createSlice({ name: 'score', initialState, reducers: { addScore: ({ score }, action) => { score += action.payload; }, // 只处理分数和网格重置的同步action resetBase: (state) => { state.score = 0; state.grid = initialState.grid; }, generateCard: (state, action) => { // 实现卡片生成逻辑 }, }, }); // 导出同步action export const { resetBase, generateCard, addScore } = scoreSlice.actions; // 定义thunk版的reset函数 export const reset = () => (dispatch) => { dispatch(resetBase()); dispatch(generateCard(2)); };
之后在组件里调用dispatch(reset())即可完成两步操作。
方案3:用Listener Middleware监听reset动作
借助Redux Toolkit的listenerMiddleware,监听reset action的触发事件,自动派发generateCard action。
import { configureStore, createListenerMiddleware } from '@reduxjs/toolkit'; // 创建监听中间件 const listenerMiddleware = createListenerMiddleware(); // 配置监听规则:当reset action被派发时,自动触发generateCard(2) listenerMiddleware.startListening({ actionCreator: scoreSlice.actions.reset, effect: (_, listenerApi) => { listenerApi.dispatch(scoreSlice.actions.generateCard(2)); }, }); // 配置store时加入该中间件 const store = configureStore({ reducer: { score: scoreSlice.reducer, }, middleware: (getDefaultMiddleware) => getDefaultMiddleware().prepend(listenerMiddleware.middleware), });
此时你的slice里的reset reducer保持原有逻辑即可:
const scoreSlice = createSlice({ name: 'score', initialState, reducers: { addScore: ({ score }, action) => { score += action.payload; }, reset: (state) => { state.score = 0; state.grid = initialState.grid; }, generateCard: (state, action) => { // 实现卡片生成逻辑 }, }, });
内容的提问来源于stack exchange,提问作者pvp11
相关产品推荐
相关产品推荐

