React中如何按分类分组展示列表内的商品
React按分类分组展示商品列表解决方案
要实现按分类分组展示(支持商品属于多个分类),核心是先将原始数据转换为按分类聚合的结构,再进行渲染。你的现有代码问题在于直接遍历商品并重复渲染分类标题,没有完成分类的聚合。
步骤1:数据分组处理
使用Array.reduce将商品按分类聚合,同一个商品会被添加到它所属的所有分类中:
// 假设Items是API返回的完整数据对象 const groupedByCategory = Items?.menu_items?.reduce((acc, item) => { item.categorys.forEach(category => { // 用分类的唯一ID作为键,避免同名分类冲突 const categoryKey = category.category_public_id; if (!acc[categoryKey]) { // 初始化分类条目,保存分类信息和商品数组 acc[categoryKey] = { ...category, items: [] }; } // 将当前商品添加到对应分类的商品列表 acc[categoryKey].items.push(item); }); return acc; }, {}); // 将分组对象转为数组,方便React渲染 const categoryGroups = Object.values(groupedByCategory || {});
步骤2:渲染分组后的列表
遍历聚合后的分类数组,每个分类下渲染对应的商品列表:
{categoryGroups.length > 0 ? ( categoryGroups.map(group => ( <div className='mb-8' key={group.category_public_id}> {/* 分类标题 */} <h2 className="text-lg font-semibold text-slate-900 py-2"> {group.category_name} </h2> {/* 商品列表 */} <ul role="list" className="-my-5 divide-y divide-gray-300"> {group.items.map(item => ( <li key={item.item_public_id} className="py-4"> <div className="flex items-center space-x-4"> {/* 商品图片 */} <img src={item.item_image} alt={item.item_name} className="w-16 h-16 object-cover rounded" /> {/* 商品信息 */} <div> <h3 className="font-medium text-slate-900">{item.item_name}</h3> <p className="text-slate-500">价格: {item.price}</p> <p className="text-sm text-slate-600">{item.ingredients}</p> </div> </div> </li> ))} </ul> </div> )) ) : ( <p className="text-slate-500">暂无商品</p> )}
原代码问题说明
你的代码是遍历每个商品,再遍历商品的分类,仅渲染商品的第一个分类标题,这会导致:
- 同一分类下的每个商品都会重复渲染一次分类标题
- 无法将同一分类的商品聚合到同一个标题下
- 商品属于多个分类时,只会显示第一个分类,其他分类的关联关系被忽略
通过先聚合数据再渲染的方式,完美解决了这些问题,同时支持商品属于多个分类的场景。
内容的提问来源于stack exchange,提问作者Gilbert Okullo
相关产品推荐
相关产品推荐

