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

如何避免FlatList中重复渲染相同id的列表项?

解决方案

核心思路有两种,优先推荐第一种预处理数据源的方案:

方案1:预处理数据源(推荐)

直接对原始数据做去重+筛选,得到纯净的待渲染收藏列表,不需要在渲染逻辑里加额外判断,性能最优,逻辑最清晰:

// 按id对原始商品数组去重,默认保留每个id出现的第一条数据,如有特殊保留规则可自行调整判断逻辑
const uniqueProductMap = new Map();
dataArray.forEach(item => {
  if (!uniqueProductMap.has(item.id)) {
    uniqueProductMap.set(item.id, item);
  }
});
// 筛选得到仅包含用户收藏的商品列表,过滤不存在的id
const renderFavList = myFavIds.map(id => uniqueProductMap.get(id)).filter(Boolean);

修改FlatList的数据源为处理后的列表,同时把keyExtractor改成用item.id,避免index作为key带来的渲染异常:

<FlatList
  data={renderFavList}
  renderItem={renderItem}
  keyExtractor={(item) => item.id}
/>

// 现在renderItem不需要再做id判断,逻辑更简洁
const renderItem = ({item, index}) => {
  return (
    <IndividualProduct
      info={item}
      index={index}
      fav={true}
      stateChange={stateChange}
      setLoading={setLoading}
    />
  );
};

方案2:渲染时过滤(仅应急使用)

如果不想改动数据源逻辑,可以用useRef存储已经渲染过的id,渲染时判断去重,注意该方案性能较差,且列表更新时需要手动清空已记录的id:

import { useRef, useEffect } from 'react';

// 组件内定义ref存储已渲染的id,避免组件重渲染时记录丢失
const renderedIdSet = useRef(new Set());

const renderItem = ({item, index}) => {
  // 同时判断是否在收藏列表、且未被渲染过
  if (myFavIds.includes(item.id) && !renderedIdSet.current.has(item.id)) {
    renderedIdSet.current.add(item.id);
    return (
      <IndividualProduct
        info={item}
        index={index}
        key={index}
        fav={true}
        stateChange={stateChange}
        setLoading={setLoading}
      />
    );
  }
  return null;
};

// 收藏列表更新时清空已记录的id,避免后续渲染异常
useEffect(() => {
  renderedIdSet.current.clear();
}, [myFavIds]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 01:06:00