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

Redux拆分Reducer:如何构建预期的状态结构

如何正确拆分Redux Reducer以实现预期状态结构

首先明确你想要的最终状态结构:

state = { 
  items: { 
    currentItem: object, 
    byId: object, 
    allIds: array, 
    fetching: bool 
  }, 
  someOtherModule: { ... } 
}

你之前尝试的两种方式都没达到预期,核心问题在于没有正确把拆分后的reducer直接映射到items对象的对应字段上。下面给你两种可行的解决方案:


方案一:拆分每个子reducer为单独文件

这是最清晰的拆分方式,每个状态字段对应一个独立的reducer文件:

  1. 准备单个子reducer文件:

    • items/reducers/currentItem.js(保留你原有的代码):
      const currentItem = (state = null, action) => {
        // 处理currentItem的action逻辑
      }
      export default currentItem;
      
    • items/reducers/byId.js:
      const byId = (state = {}, action) => {
        // 处理byId的action逻辑
      }
      export default byId;
      
    • items/reducers/allIds.js:
      const allIds = (state = [], action) => {
        // 处理allIds的action逻辑
      }
      export default allIds;
      
    • items/reducers/fetching.js:
      const fetching = (state = false, action) => {
        // 处理fetching状态的action逻辑
      }
      export default fetching;
      
  2. 在items/reducers/index.js中组合所有子reducer:
    直接导入每个子reducer,通过combineReducers映射到items对象的对应字段:

    import { combineReducers } from 'redux';
    import currentItem from './currentItem';
    import byId from './byId';
    import allIds from './allIds';
    import fetching from './fetching';
    
    export default combineReducers({
      currentItem,
      byId,
      allIds,
      fetching
    });
    
  3. 根reducer中导入组合好的items reducer:

    import { combineReducers } from 'redux';
    import items from './items/reducers';
    import someOtherModule from './someOtherModule/reducers';
    
    export default combineReducers({
      items,
      someOtherModule
    });
    

这样就能完美得到你想要的状态结构,没有多余嵌套,每个字段对应独立的reducer逻辑。


方案二:合并部分子reducer到同一文件

如果不想拆分太多文件,可以把byId、allIds、fetching放在同一个文件导出,再在index.js中逐个导入组合:

  1. items/reducers/items.js:

    export const byId = (state = {}, action) => {
      // 处理byId的逻辑
    }
    
    export const allIds = (state = [], action) => {
      // 处理allIds的逻辑
    }
    
    export const fetching = (state = false, action) => {
      // 处理fetching的逻辑
    }
    
  2. items/reducers/index.js:
    从items.js中解构出每个子reducer,再和currentItem一起组合:

    import { combineReducers } from 'redux';
    import currentItem from './currentItem';
    import { byId, allIds, fetching } from './items';
    
    export default combineReducers({
      currentItem,
      byId,
      allIds,
      fetching
    });
    
  3. 根reducer写法和方案一完全一致,最终状态结构也符合预期。


为什么你之前的方式不行?

  • 方式一和方式二中,你把包含byId等的item对象直接传给combineReducers,但combineReducers要求每个值是单个reducer函数,而非对象,所以Redux不会展开这个对象,导致最终items下只有currentItem。
  • 若在items.js里先自行combineReducers({byId, allIds, fetching}),会把这三个字段包裹在额外的items嵌套中,不符合你的预期。

内容的提问来源于stack exchange,提问作者user210757

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:08:31