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
相关产品推荐
相关产品推荐

