
本文介绍如何通过递归式请求分页 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>
);
};
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 响应元数据驱动数据聚合过程,兼具健壮性与可维护性。


















