React分页API调用与多页数据加载问题解决
React分页加载对接方案与异常修复
原有代码问题定位
现有代码的异常来自几个核心逻辑错误:
- 状态定义错误:
page作为页码初始值设为空数组,类型完全不匹配;定义的load状态全程没有实际作用,属于冗余代码 - 数据覆盖逻辑错误:每次接口返回后直接用
setUserList(res.elements)替换全量列表,之前加载的数据会被清空,是按钮异常消失的核心诱因 - 页码更新冲突:请求回调里执行
setPage(res.page),和点击按钮时的页码+1逻辑冲突,直接导致页码错乱 - 无终止判断:没有基于接口返回的
total字段判断是否加载完全部数据,所有数据拉完后还会继续发起无效请求 - loading状态不全:只有返回空数组时才会关闭loading,正常请求结束后loading不会重置,按钮状态会持续异常
1. 1000条单次限制下加载全量5000条数据的实现
接口虽然没有直接返回总页数,但已经返回了总记录数total和单页条数pageSize,直接用Math.ceil(total / pageSize)就能算出总页数,5000条数据对应总页数为5。
请求逻辑遵循三个规则即可:
- 页面初始化时自动加载第1页的1000条数据
- 每次点击加载更多时页码+1,请求对应页数据,拿到结果后追加到现有列表尾部,绝对不能覆盖原有数据
- 当当前已加载的数据条数大于等于
total时,立刻停止发起新请求
2. 加载按钮交互异常修复
按钮逻辑增加三个判断即可解决所有交互异常:
- 请求过程中按钮显示「Loading...」且禁用,避免重复点击发送重复请求
- 当判断还有未加载的数据时,按钮正常显示为可点击状态
- 当所有数据加载完成后,按钮直接隐藏,或者替换为「没有更多数据」的提示,不会出现无故消失的问题
修复后可直接运行的完整代码
import { useState, useEffect } from 'react'; const perPage = 1000; function App() { // 修正page初始值为数字1,移除无用的load状态 const [page, setPage] = useState(1); const [userList, setUserList] = useState([]); const [loading, setLoading] = useState(false); const [total, setTotal] = useState(0); useEffect(() => { const getUserList = async () => { setLoading(true); try { const res = await fetch(`/forms?page=${page}&count=${perPage}`, { headers }); const data = await res.json(); // 存储总记录数用于判断是否加载完成 setTotal(data.total); // 新数据追加到原有列表,不覆盖历史数据 setUserList(prev => [...prev, ...data.elements]); } catch (err) { console.error('加载数据失败:', err); } finally { // 无论请求成功失败都关闭loading状态 setLoading(false); } }; getUserList(); }, [page]); // 计算是否还有更多未加载数据 const hasMore = userList.length < total; return ( <div className="App"> {userList.map((x, i) => { return ( <div key={x.id || i} className="box"> <div className="name">{x.name}</div> </div> ); })} {/* 只有还有更多数据的时候才显示加载按钮 */} {hasMore && ( <button className="btn-load-more" onClick={() => setPage(p => p + 1)} disabled={loading} > {loading ? "Loading..." : "Load More"} </button> )} </div> ); } export default App;
关键修复点说明
- 修正状态类型:页码初始值设为数字1,移除无意义的冗余状态,从根源避免类型错误导致的逻辑异常
- 调整数据更新逻辑:用函数式更新把新一页的数据追加到原列表尾部,保证已加载的数据不会丢失
- 增加加载终止判断:通过对比已加载数据长度和总记录数判断是否还有剩余数据,加载完成后自动隐藏按钮,不会发起无效请求
- 移除冲突的页码更新逻辑:不再在请求回调里强制修改page值,页码完全由前端点击逻辑维护,避免页码错乱
- 完善loading状态:用
finally保证无论请求成功失败都会重置loading状态,按钮不会卡在异常状态 - 列表key优先用数据唯一id,避免索引作为key导致的渲染异常
内容的提问来源于stack exchange,提问作者mmz
相关产品推荐
相关产品推荐

