如何在React中对不同Bucket分组的Contents对象进行无重复映射?
解决React中按Bucket分组渲染Contents且无重复的问题
看起来你之前的尝试要么是逐个遍历原数组导致同一Bucket重复渲染,要么只是筛选出特定Bucket但没合并Contents。其实核心思路是先把同一Bucket下的所有Contents合并到一起,再按Bucket分组渲染,这样就能避免重复,同时每个Bucket只渲染一次。
第一步:分组并合并Contents
我们可以用数组的reduce方法,把原数组按bucket.code分组,同时把每个分组下的contents合并成一个数组:
const listData = [ { "_id":"abscdf456", "bucket": {code: "videos"}, "contents": [ {}, {}, {}, {} ] }, { "_id":"absusi789", "bucket": {code: "videos"}, "contents": [ {}, {}, {}, {}, {}, {} ] }, { "_id":"abssth7890", "bucket": {code: "photos"}, "contents": [ {}, {}, {}, {},{}, {},{}, {}, {} ] }, { "_id":"yuiaf456", "bucket": {code: "videos"}, "contents": [ {}, {}, {} ] } ]; // 按bucket.code分组,合并对应contents const groupedData = listData.reduce((acc, currentItem) => { const bucketKey = currentItem.bucket.code; // 如果当前Bucket还没在分组对象里,初始化空数组 if (!acc[bucketKey]) { acc[bucketKey] = []; } // 把当前item的contents合并到对应Bucket的数组中 acc[bucketKey] = [...acc[bucketKey], ...currentItem.contents]; return acc; }, {});
执行后,groupedData会是这样的结构:
{ videos: [/* 所有videos下的contents对象合并后的数组 */], photos: [/* 所有photos下的contents对象合并后的数组 */] }
第二步:分组渲染
接下来我们把分组后的对象转换成键值对数组,然后逐个渲染每个Bucket及其对应的Contents:
return ( <div className="bucket-container"> {/* 遍历分组后的键值对 */} {Object.entries(groupedData).map(([bucketName, contentsList]) => ( <div key={bucketName} className="bucket-section"> {/* 渲染Bucket标题,首字母大写 */} <h2>{bucketName.charAt(0).toUpperCase() + bucketName.slice(1)}</h2> {/* 渲染当前Bucket下的所有Contents */} {contentsList.map((content, idx) => ( {/* 注意:如果content有唯一id,优先用id作为key,不要用idx */} <div key={idx} className="content-item"> {/* 这里替换成你要渲染的content内容 */} 内容项 {idx + 1} </div> ))} </div> ))} </div> );
为什么之前的方法不行?
- 第一种
map+条件判断的方式:会遍历原数组的每一项,同一个Bucket的每个item都会生成一个独立的区块,自然会重复渲染Bucket标题和分散的Contents。 - 第二种
filter的方式:只是筛选出了特定Bucket的item,但还是逐个渲染这些item,Contents并没有合并,所以还是分散的,无法实现“每个Bucket对应所有Contents”的需求。
这个方法的好处是:不管原数组有多少个同一Bucket的item,最终每个Bucket只会渲染一次,且所有对应的Contents都合并到一起,完全满足你的无重复映射需求。
内容的提问来源于stack exchange,提问作者Pranav
相关产品推荐
相关产品推荐

