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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:15:53