如何将分类状态与项目数组合并为嵌套结构的单一状态?
解决方案:按分类合并项目数组与分类状态
问题分析
你原来的代码用map遍历项目数组时,每一项都会生成一个独立的{[分类名]: {items: [当前项]}}对象,之后用扩展运算符合并这些对象时,同分类的键会被后面的对象覆盖,导致每个分类最后只剩最后一个匹配的项目,这就是你遇到覆盖问题的原因。
正确实现方式
我们可以用Array.reduce()来遍历项目数组,逐步累积出目标结构。下面提供两种方案:
方案1:基于已有分类状态合并
如果需要保留原分类状态的结构(比如原分类里有其他属性),可以从原分类状态开始,把项目数组里的项逐个添加到对应分类的items数组中:
// 假设原分类状态是categoryState,项目数组是items const mergedState = items.reduce((acc, item) => { const category = item.itemInfo.category; // 如果分类不存在,就用原分类的结构(如果原分类里有的话),否则初始化 acc[category] = acc[category] || { items: [] }; // 把当前项目添加到对应分类的items数组 acc[category].items.push(item); return acc; }, { ...categoryState }); // 复制原分类状态作为初始值 setFinalState(mergedState);
方案2:直接从项目数组生成完整结构
如果不需要依赖原分类状态,直接从项目数组生成目标结构:
const mergedState = items.reduce((acc, item) => { const category = item.itemInfo.category; // 初始化分类的items数组(如果还没创建) if (!acc[category]) { acc[category] = { items: [] }; } acc[category].items.push(item); return acc; }, {} as Record<string, { items: typeof items }>); // 类型定义,避免any setFinalState(mergedState);
代码说明
reduce的第一个参数是累积函数,acc是我们要构建的最终对象,每次遍历都会把当前项目放到对应的分类数组里。- 这样每个分类的
items数组会逐步收集所有匹配的项目,不会出现覆盖问题。
内容的提问来源于stack exchange,提问作者Dglfwcfa
相关产品推荐
相关产品推荐

