Redux Toolkit跨Slice调用Reducer报错,求可行实现方案
跨Slice状态更新的正确实现方式
首先明确:Redux完全支持跨Slice的状态修改,你的报错只是因为触发方式错误。
错误原因
你在sliceB的extraReducer里试图通过action.payload.dispatch(increment())触发sliceA的action,但**action.payload是异步thunk返回的业务数据,并不包含dispatch方法**,自然会报错。
推荐实现方案
方案1:在异步thunk内部直接触发其他Slice的Action
异步thunk函数可以获取到dispatch参数,在异步操作完成后直接调用dispatch触发sliceA的action,这是最直接的写法:
// sliceB.js import { createAsyncThunk } from '@reduxjs/toolkit'; import { increment } from './sliceA'; export const fetchData = createAsyncThunk( 'sliceB/fetchData', async (params, { dispatch }) => { // 执行异步操作 const response = await fetch('/api/data'); const data = await response.json(); // 异步操作完成后,触发sliceA的action dispatch(increment()); return data; } );
方案2:在目标Slice的extraReducer中监听异步操作完成的Action
让sliceA直接监听sliceB异步thunk完成的action,在自己的reducer里更新状态,这种方式更符合Redux“reducer响应action”的设计模式:
// sliceA.js import { createSlice } from '@reduxjs/toolkit'; import { fetchData } from './sliceB'; const sliceA = createSlice({ name: 'sliceA', initialState: { count: 0 }, reducers: { increment: (state) => { state.count += 1; } }, extraReducers: (builder) => { // 监听sliceB中fetchData异步操作完成的action builder.addCase(fetchData.fulfilled, (state) => { // 直接更新sliceA的状态 state.count += 1; }); } }); export const { increment } = sliceA.actions; export default sliceA.reducer;
方案3:通过全局store的dispatch触发(不推荐)
如果在某个非组件、非thunk的场景需要触发action,可以直接从store实例调用dispatch,但这种方式会增加代码耦合,不建议在slice内部使用:
// store.js export const store = configureStore({ reducer: { sliceA: sliceAReducer, sliceB: sliceBReducer } }); // 在需要的地方调用 import { store } from './store'; import { increment } from './sliceA'; store.dispatch(increment());
总结
优先选择方案1或方案2,前者适合需要在异步操作完成后执行多个副作用的场景,后者更符合Redux的单向数据流设计,代码耦合度更低。
内容的提问来源于stack exchange,提问作者Sammybar
相关产品推荐
相关产品推荐

