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

React加载更多功能初始数据重复问题求助

React Load More初始加载数据重复问题解决办法

问题描述

实现Load More功能,要求初始展示2条用户详情,点击“Load More”按钮加载剩余用户数据,但页面初始加载时出现数据重复,后续加载功能正常。

问题代码

import { useState, useEffect } from "react";

const LoadMoreComponent = () => {
  const [data, setData] = useState([]);
  const [page, setPage] = useState(1);
  const [totalPage, setTotalPage] = useState(0);

  const [loading, setLoading] = useState(false);
  useEffect(() => {
    const fetchData = async () => {
      try {
        setLoading(true);
        const response = await fetch(
          `https://reqres.in/api/users?page=${page}&per_page=2`
        );
        const result = await response.json();
        setLoading(false);
        setData((prev) => [...prev, ...result.data]);
        setTotalPage(result.total_pages);
        console.log(data);
      } catch (error) {
        console.log(error);
      }
    };

    fetchData();
  }, [page]);

  return (
    <div>
      <div>
        {data && data.map((user) => (
          <div key={user.id}>
            <h3>
              {user.first_name} {user.last_name}
            </h3>
          </div>
        ))}
      </div>
      <div>
        {page < totalPage && (
          <button onClick={() => setPage(page + 1)}> Load More </button>
        )}
      </div>
    </div>
  );
};

export default LoadMoreComponent;

问题原因

这是React**开发环境下严格模式(Strict Mode)**导致的:Strict Mode会刻意重复执行某些生命周期函数(包括useEffect),目的是帮开发者提前发现潜在bug。你的代码中page初始值为1,所以useEffect会被触发两次,两次请求page=1的接口,每次都把返回的2条数据追加到data里,最终初始数据变成4条(重复的2条)。

解决方案

以下是几种可行的解决办法,按推荐程度排序:

1. 数据追加时自动去重(最推荐,健壮性高)

修改setData的逻辑,在添加新数据前过滤掉已存在的用户(通过id判断),即使重复请求接口也不会出现重复数据:

setData((prev) => {
  // 筛选出当前data中没有的新用户
  const uniqueNewUsers = result.data.filter(user => 
    !prev.some(existingUser => existingUser.id === user.id)
  );
  return [...prev, ...uniqueNewUsers];
});

2. 用Ref控制首次加载的重复执行

通过useRef标记是否为首次渲染,在Strict Mode的第二次执行时跳过请求:

import { useState, useEffect, useRef } from "react"; // 引入useRef

const LoadMoreComponent = () => {
  const [data, setData] = useState([]);
  const [page, setPage] = useState(1);
  const [totalPage, setTotalPage] = useState(0);
  const [loading, setLoading] = useState(false);
  const isFirstRender = useRef(true); // 添加ref标记

  useEffect(() => {
    const fetchData = async () => {
      try {
        setLoading(true);
        const response = await fetch(
          `https://reqres.in/api/users?page=${page}&per_page=2`
        );
        const result = await response.json();
        setLoading(false);
        setData((prev) => [...prev, ...result.data]);
        setTotalPage(result.total_pages);
      } catch (error) {
        console.log(error);
      }
    };

    if (isFirstRender.current) {
      isFirstRender.current = false;
      // 开发环境Strict Mode下,只执行一次首次请求
      fetchData();
    } else {
      // page变化时正常执行请求
      fetchData();
    }
  }, [page]);

  // 其余代码不变...
};

3. 关闭严格模式(仅临时验证,不推荐长期使用)

在项目入口文件(通常是index.js)中,去掉<StrictMode>标签。但Strict Mode能帮你提前发现很多潜在问题,所以不建议长期关闭。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:58:19