You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redux Toolkit相关问题:reducers与extraReducers能否共存及createAsyncThunk未调用排查

Redux Toolkit相关问题:reducers与extraReducers能否共存及createAsyncThunk未调用排查

我来帮你逐个分析并解决这两个问题:


问题1:reducers和extraReducers能否同时使用?

完全可以! Redux Toolkit的设计就是支持两者共存的,它们各司其职:

  • reducers 用来处理你自己定义的同步action,比如你代码里的add、remove这类用于组件内部状态操作的action,这些action会自动生成对应的action creator。
  • extraReducers 用来处理外部action,比如createAsyncThunk生成的异步action(pending/fulfilled/rejected状态),或者来自其他slice的action。

你当前的用法是完全合理的:用extraReducers处理API请求的异步状态,用reducers处理添加/删除行这类本地状态更新,没有任何问题。


问题2:fetchResuorces为什么没有被默认调用?

看你的代码,核心问题出在useEffect里的dispatch调用上,另外还有几个潜在的错误需要修正:

1. 最直接的错误:dispatch时没有调用thunk函数

在你的ResourceComponent的useEffect中,你写的是:

useEffect(() => {
  dispatch(fetchResuorces)
}, [])

但fetchResuorces是createAsyncThunk返回的action creator函数,你需要调用它才能生成可被dispatch的action,正确写法是:

useEffect(() => {
  dispatch(fetchResuorces()) // 这里要加括号!
}, [dispatch]) // 别忘了把dispatch加入依赖数组,避免lint警告

2. 检查store是否正确配置

你没有提供store的代码,要确保你已经把resourceSlice.reducer加入到了Redux store的reducers中,比如:

// store.js示例
import { configureStore } from '@reduxjs/toolkit';
import resourceReducer from './resourceSlice';

export const store = configureStore({
  reducer: {
    resource: resourceReducer, // 必须把resource reducer注册到store里
  },
});

如果没注册,你的slice状态根本不会被Redux管理,dispatch的action也不会触发对应的reducer。

3. extraReducers中fulfilled case的错误

你当前的fulfilled处理会直接替换整个state:

.addCase(fetchResuorces.fulfilled, (state, action) => {
  console.log('fulfilled')
  return action.payload
})

这会导致原来state里的rows等属性完全丢失,因为你把整个state替换成了action.payload。正确的做法是只更新需要的部分,比如你想把API返回的角色数据赋值给state.roles:

.addCase(fetchResuorces.fulfilled, (state, action) => {
  console.log('fulfilled')
  state.roles = action.payload; // 只更新roles属性,保留rows等其他状态
})

4. remove reducer的错误

你的remove reducer直接返回了过滤后的rows数组,这会把整个state变成数组,而不是原来包含rows和roles的对象:

remove(state, action) {
  console.log('remove called')
  console.log(state.rows)
  return state.rows.filter((item, index) =>
    item.id !== action.payload
  );
}

正确的写法应该是修改state的rows属性(Redux Toolkit的Immer会帮你处理不可变更新):

remove(state, action) {
  console.log('remove called')
  // 注意:你的rows元素里只有index,没有id,所以应该用index来过滤
  state.rows = state.rows.filter((item, index) => index !== action.payload);
}

另外,你的rows初始数据是[{index:1}],没有id属性,所以之前的item.id !== action.payload永远为true,过滤不会生效,要改成用index来判断。


备注:内容来源于stack exchange,提问作者Deep Kakkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 10:18:06