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

API调用对象重复问题:无限滚动场景下初始数据重复的解决方法咨询

解决无限滚动首次加载数据重复的问题

看起来你遇到的是首次加载数据重复,但后续滚动加载完全正常的情况,我来帮你梳理几种常见原因和对应的解决办法:

1. 组件初始化时API请求被触发多次

这是最常见的问题——比如在useEffect里没设置正确的依赖项,或者开发模式下React的StrictMode(严格模式)会强制组件重复渲染一次,导致首次请求被执行了两次。

解法:

  • 先检查useEffect的依赖数组,确保只在组件挂载时(依赖传空数组[])执行一次请求:
    useEffect(() => {
      fetchFirstBatch();
    }, []); // 空依赖确保仅组件挂载时执行一次
    
  • 如果是StrictMode导致的重复渲染,可以给请求加一个加载锁,避免重复发起请求:
    const [isLoading, setIsLoading] = useState(false);
    
    const fetchFirstBatch = async () => {
      if (isLoading) return; // 已有请求在进行时直接返回
      setIsLoading(true);
      try {
        const res = await fetch('你的API地址');
        const data = await res.json();
        setStickers(data); // 首次加载直接替换数组,不是合并
      } catch (err) {
        console.error('请求出错:', err);
      } finally {
        setIsLoading(false);
      }
    };
    

2. 初始状态更新错误使用了数组合并逻辑

如果你的初始状态是空数组,而首次请求后错误地用setStickers(prev => [...prev, ...newData])来更新状态,一旦这个逻辑被执行两次,就会导致首次数据重复。

解法:

区分首次加载和滚动加载的更新逻辑:

// 首次加载时直接替换数组
setStickers(newData);

// 后续滚动加载时再合并新数据
setStickers(prev => [...prev, ...newData]);

你可以用一个状态(比如isFirstLoad)来标记是否是首次加载,或者直接在初始化请求里用替换逻辑,滚动加载用合并逻辑。

3. API返回的初始数据本身就有重复

虽然你说后续滚动没问题,但也可以先排查下首次调用API的响应数据——在控制台打印首次请求返回的data,看看是不是API本身就返回了重复的GIF条目。

解法:

如果API确实返回了重复数据,可以在存入状态前做去重处理(假设每个贴纸有唯一的id字段):

// 利用Map去重,保留最后出现的重复项
const uniqueData = [...new Map(newData.map(item => [item.id, item])).values()];
setStickers(uniqueData);

4. 列表渲染的key值不唯一

如果渲染列表时用了索引作为key,或者key值重复,可能会导致React渲染时出现视觉上的重复(哪怕数据本身是唯一的)。

解法:

确保每个列表项的key是唯一且稳定的,比如使用每个贴纸的唯一ID:

{stickers.map(sticker => (
  <div key={sticker.id} className="sticker-card">
    <img src={sticker.gifUrl} alt={sticker.title} />
  </div>
))}

你可以按照这个顺序排查,应该能很快定位到问题所在~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 13:07:43