
本文介绍如何通过递归式请求分页 api(如 laravel 分页响应),在 react 中自动遍历所有页面并合并数据,避免手动翻页或硬编码页数。
本文介绍如何通过递归式请求分页 api(如 laravel 分页响应),在 react 中自动遍历所有页面并合并数据,避免手动翻页或硬编码页数。
在实际开发中,后端常采用分页策略(如 Laravel 的 LengthAwarePaginator)返回数据,响应中包含 next_page_url、last_page 等元信息。若仅调用一次 getJobs(),则只能获取第一页的 10 条数据。要获取全部 13 条(或成百上千条)记录,需自动链式请求后续页面,直到无下一页为止。
核心思路是:将分页控制逻辑交由 React 状态驱动——用 nextPage 状态标识待请求的 URL,每次请求成功后更新该状态;当 nextPage 变为 null(即无更多页面)时,自动停止请求。这本质上是“状态驱动的异步循环”。
以下是优化后的完整实现:
import React, { useState, useEffect } from 'react';
import { getJobsByURL } from '../service/jobs'; // 修改为支持传入 URL 的版本
const MyTable = () => {
const [data, setData] = useState([]);
const [nextPage, setNextPage] = useState('http://api/api/v1/jobs?page=1');
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
// 自动请求下一页(依赖 nextPage 变化)
useEffect(() => {
if (!nextPage) {
setLoading(false);
return;
}
setLoading(true);
getJobsByURL(nextPage)
.then((response) => {
const newData = response.data.data.data || [];
setData(prev => [...prev, ...newData]);
setNextPage(response.data.next_page_url); // 如响应中为 null,则下次 effect 不触发
})
.catch((err) => {
console.error('Failed to fetch jobs:', err);
setError(err.message);
setLoading(false);
});
}, [nextPage]);
// 可选:添加加载状态提示
if (loading && data.length === 0) return <div>Loading all jobs...</div>;
if (error) return <div>Error: {error}</div>;
return (
<div>
{data.map((d, key) => (
<div key="{key}" classname="d-flex">
<h1>{d.id}</h1>
<h1>{d.job_title}</h1>
</div>
))}
<p>Total records loaded: {data.length}</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill7457" title="Ink — React for interactive command-line apps."><img
src="https://img.php.cn/upload/skill/000/000/081/179151488712051.jpg" alt="Ink — React for interactive command-line apps." onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill7457" title="Ink — React for interactive command-line apps." class="overflowclass">Ink — React for interactive command-line apps.</a>
<p class="overflowclass">Ink — 用 React 开发交互式命令行应用,使用 React组件构建丰富的终端 UI。</p>
</div>
<a rel="nofollow" href="/xiazai/skill7457" title="Ink — React for interactive command-line apps." class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
</div>
);
};
export default MyTable;
同时,请更新你的服务函数以支持动态 URL:
// ../service/jobs.ts
export function getJobsByURL(url: string) {
return axiosClient.get(url);
}
// 原 getJobs() 可保留为默认第一页快捷调用
export function getJobs() {
return getJobsByURL('/jobs');
}
⚠️ 关键注意事项:
- ✅ 依赖项必须精准:useEffect 仅监听 [nextPage],确保不会因 data 变化引发无限请求;
- ✅ 空值终止机制:next_page_url 为 null 或 undefined 时,setNextPage(null) 将使 effect 跳过后续请求;
- ⚠️ 错误处理不可省略:单页失败不应中断整个链路,但需记录并停止后续请求(示例中已体现);
- ⚠️ 性能与体验优化建议:
- 对大量数据(如 >1000 条),可考虑添加防抖、节流或分批渲染(如 React.memo + 虚拟滚动);
- 生产环境建议增加请求超时(axiosClient 配置 timeout: 10000)和重试机制;
- 若后端支持 ?page=1&per_page=100,优先尝试增大单页数量而非多请求——更高效。
通过该模式,你无需预知总页数,也无需手动管理循环索引,完全由 API 响应元数据驱动数据聚合过程,兼具健壮性与可维护性。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










