Redux Toolkit中如何在一个reducer内调用另一个reducer的方法
解决方案
为什么catReducer.caseReducers.eat()调用不生效
每个slice的case reducer只接收自身切片的state作为入参执行逻辑,你在user reducer中调用时如果传递的是user切片的state,自然无法操作cat切片的状态,也不会有预期效果。
Redux的设计原则就是每个reducer独立管理自己的状态切片,reducer之间不直接互相调用修改对方状态,你可以通过下面两种常见方案实现需求:
方案1:通过extraReducers响应同个action(推荐,符合Redux设计规范)
如果feedCat触发时需要同时修改user切片和cat切片的状态,直接让cat切片监听feedCat这个action即可,不需要在user reducer里主动调用cat的方法:
- 在
cat.reducer.js中引入feedCataction,添加extraReducers配置:
// cat.reducer.js import { createSlice } from '@reduxjs/toolkit'; // 新增引入user的feedCat action import { feedCat } from './user.reducer'; const initialState = { id: null, name: null, age: null, color: null, foodLevel: null, healthLevel: null, weight: null, }; const reducer = createSlice({ name: 'cat', initialState, reducers: { createCat: ( state, { payload: { id, name, age, color, foodLevel, healthLevel, weight, }, } ) => { state = { id: id, name, age, color, foodLevel, healthLevel, weight, }; return state; }, eat: (state, action) => { console.log('hello from cat'); state.foodLevel += 10; // 业务逻辑示例 }, }, // 新增extraReducers监听feedCat动作 extraReducers: (builder) => { builder.addCase(feedCat, (state, action) => { // 直接复用eat的逻辑,这里的state就是cat切片自己的状态 reducer.caseReducers.eat(state, action); }) } }); export const { createCat, eat } = reducer.actions; export const catReducer = reducer.reducer;
- 此时你只要正常dispatch
feedCat动作,两个切片的reducer都会响应执行对应逻辑,不需要在user的feedCatreducer里写额外代码。
方案2:抽离公共逻辑复用(适合user切片存储cat列表的场景)
如果你的cat状态是直接存在user切片的cats数组里,没有独立的cat状态切片,可以直接把eat的逻辑抽出来复用:
- 先在
cat.reducer.js里导出eat的case reducer:
// cat.reducer.js 末尾新增导出 export const eatLogic = reducer.caseReducers.eat;
- 在
user.reducer.js里引入后调用,注意要传入对应cat的状态作为入参:
// user.reducer.js import { createSlice } from '@reduxjs/toolkit'; import { eatLogic } from './cat.reducer'; const initialState = { id: 123, name: 'Owner123', cats: [], }; const reducer = createSlice({ name: 'user', initialState, reducers: { addCat: (state, action) => { // RTK支持直接修改state,不需要手动解构返回,原有写法也兼容 state.cats.push(action.payload); }, feedCat: (state, action) => { // 假设payload是要喂的猫的id const targetCat = state.cats.find(cat => cat.id === action.payload); if (targetCat) { // 传入cat对象作为state参数调用eat逻辑 eatLogic(targetCat, action); } }, }, }); export const { addCat, feedCat } = reducer.actions; export const userReducer = reducer.reducer;
内容的提问来源于stack exchange,提问作者Evgenii Komornyi
相关产品推荐
相关产品推荐

