Redux Toolkit中signOut的createAsyncThunk完成后如何触发另一slice的clearCart
问题原因与解决方案
1. Immer报错的直接原因
你cartSlice中的clearCart reducer写法不符合Immer规则:
clearCart: (state) => { return (state.cartItems = []); }
这段代码同时做了两个Immer禁止的操作:修改了草稿状态的cartItems属性,又返回了赋值表达式的结果,Immer无法判断该以哪个值作为最终状态,就会抛出你遇到的冲突错误。
修复方案二选一即可:
- 仅修改草稿不返回值:
clearCart: (state) => { state.cartItems = []; }
- 仅返回新状态不修改草稿:
clearCart: () => ({ hidden: true, cartItems: [] })
2. 登出时清空购物车的两种实现方案
方案一:在signOut thunk中直接派发clearCart
你之前的实现思路是正确的,只需要先修复clearCart的写法,再调整thunk代码即可:
// userSlice.js import { clearCart } from './cartSlice'; // 按你的实际路径调整导入 export const signOut = createAsyncThunk( "user.signOut", async (_, { rejectWithValue, dispatch }) => { try { await auth.signOut(); dispatch(clearCart()); // 登出完成后直接派发清空购物车动作 } catch (error) { return rejectWithValue(error.message); } } );
方案二:在cartSlice中监听signOut完成动作(更推荐)
这个方案和你之前用saga监听SIGNOUT_SUCCESS的思路完全一致,逻辑更内聚,不需要跨模块修改thunk代码:
首先在cartSlice中导入signOut thunk:
// cartSlice.js import { signOut } from './userSlice'; // 按你的实际路径调整导入
再给cartSlice添加extraReducers配置:
export const cartSlice = createSlice({ name: "cart", initialState, reducers: { // 原有reducer保持不变,记得先修复clearCart的写法 // ... }, // 新增监听逻辑 extraReducers: (builder) => { builder.addCase(signOut.fulfilled, (state) => { state.cartItems = []; // 如果登出后需要同时隐藏购物车侧边栏,可额外加 state.hidden = true }) } });
内容的提问来源于stack exchange,提问作者Christos
相关产品推荐
相关产品推荐

