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

React Native渲染列表时去除重复分组表头的实现方法

问题原因

当前遍历逻辑对userProducts数组的每一条数据都渲染了一次分组表头(即展示num字段的Text组件),没有做同组表头的单次渲染判断,因此相同num标识的分组下,每一条列表项都会带出重复的表头。

修复方法

方案1:最小改动,遍历中判断表头渲染时机

不需要提前处理原始数据,只需要在map遍历时拿到当前项索引,判断当前项是否为所在分组的第一项,只有第一项才渲染分组表头即可。
注意遍历生成的外层元素需要补充唯一key属性,避免React抛出渲染警告。
修改后的ScrollView内渲染代码如下:

<ScrollView>
  {userProducts.length > 0 ? (
    userProducts.map((userProduct, index) => {
      // 仅当是数组第一项、或当前项和上一项num值不同时,才渲染分组表头
      const showHeader = index === 0 || userProducts[index - 1].num !== userProduct.num;
      return (
        <React.Fragment key={userProduct.product_id}>
          {showHeader && <Text style={{fontWeight: 'bold'}}>{userProduct.num}</Text>}
          <ListItem
            title={userProduct.product + ' x' + userProduct.amount}
            onPress={async () => {
              await deleteProduct(userProduct.product_id);
              console.log('deleted');
              getUserProducts();
              ToastAndroid.show('Done', ToastAndroid.SHORT);
            }}
            trailing={<Text>{userProduct.num}</Text>}
          />
        </React.Fragment>
      )
    })
  ) : (
    <Text>Nothing in your list yet</Text>
  )}
</ScrollView>

注意:该方案要求userProducts数组已经按num字段做过排序,相同num的项是连续排列的,如果原始数据是乱序的,需要先对数组按num字段排序后再遍历。

方案2:提前聚合分组数据,结构更易扩展

如果后续需要做分组折叠、分组计数等功能,可以先把原始数组按num字段聚合成分组结构,再做两层遍历:先遍历分组渲染表头,再遍历分组下的列表项。
示例代码如下:

// 渲染前先处理得到分组结构
const groupedProducts = userProducts.reduce((groups, product) => {
  const groupKey = product.num;
  if (!groups[groupKey]) {
    groups[groupKey] = [];
  }
  groups[groupKey].push(product);
  return groups;
}, {} as Record<string, ProductType[]>);

// 渲染部分修改为
<ScrollView>
  {userProducts.length > 0 ? (
    Object.entries(groupedProducts).map(([groupNum, products]) => (
      <React.Fragment key={groupNum}>
        <Text style={{fontWeight: 'bold'}}>{groupNum}</Text>
        {products.map(userProduct => (
          <ListItem
            key={userProduct.product_id}
            title={userProduct.product + ' x' + userProduct.amount}
            onPress={async () => {
              await deleteProduct(userProduct.product_id);
              console.log('deleted');
              getUserProducts();
              ToastAndroid.show('Done', ToastAndroid.SHORT);
            }}
            trailing={<Text>{userProduct.num}</Text>}
          />
        ))}
      </React.Fragment>
    ))
  ) : (
    <Text>Nothing in your list yet</Text>
  )}
</ScrollView>

该方案不要求原始数组按num排序,分组逻辑会自动把相同num的项聚合到同一个表头下。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:33:28