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

如何在React中使用Axios获取API的所有分页数据

如何一次性获取API分页的所有数据?

我尝试从API获取数据,该API返回多页结果:第一页包含10条数据,剩余数据分布在后续页面中。目前我通过常规Axios请求仅能获取第一页的10条数据,请问如何一次性获取所有分页的数据?


现有代码及API信息

组件代码

import React from "react";
import { useState, useEffect } from "react";
import { getJobs } from "../service/jobs";

const MyTable = () => {
  const [data, setData] = useState([]);


  useEffect(() => {
    getJobs()
      .then(function (response) {
        setData(response.data.data.data);
        console.log(response)
      })
      .catch((e) => {
        console.log("Jobs error", e);
      });
  }, []);

 

  useEffect(() => {
    console.log(data);
  }, [data]);

  return (
    <div>
      {data &&
        data.map((d, key) => (
          <div key={key} className="d-flex">
            <h1>{d.id}</h1>
            <h1>{d.job_title}</h1>
            
          </div>
        ))}
    </div>
  );
};

export default MyTable;

API响应结构

data: 
current_page: 1
data: (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
first_page_url: "http://api/api/v1/jobs?page=1"
from: 1
last_page: 2
last_page_url: "http://api/api/v1/jobs?page=2"
links: (4) [{…}, {…}, {…}, {…}]
next_page_url: "http://api/api/v1/jobs?page=2"
path: "http://api/api/v1/jobs"
per_page: 10
prev_page_url: null
to: 10
total: 13

getJobs函数

export function getJobs() {
  return axiosClient.get("/jobs");
}

axiosClient配置

const axiosClient = axios.create({
    baseURL: api_url_v1,
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${accessToken}`,
    }
  });

解决方案

从API响应可以看到,返回结果包含last_page(总页数)和next_page_url(下一页链接),我们可以基于这两个字段实现批量请求所有页面并合并数据。

步骤1:修改getJobs函数支持分页参数

先让getJobs可以接收页码参数,方便请求指定页面:

export function getJobs(page = 1) {
  return axiosClient.get(`/jobs?page=${page}`);
}

步骤2:实现批量请求逻辑

提供两种实现方式,可根据需求选择:

方式一:并行请求所有页面(高效)

适合已知总页数的场景,用Promise.all一次性发起所有剩余页面的请求,效率更高:

import React from "react";
import { useState, useEffect } from "react";
import { getJobs } from "../service/jobs";

const MyTable = () => {
  const [data, setData] = useState([]);

  useEffect(() => {
    const fetchAllJobs = async () => {
      try {
        // 获取第一页数据,拿到总页数
        const firstPageRes = await getJobs();
        const { last_page, data: firstPageData } = firstPageRes.data.data;
        
        // 只有一页的情况直接返回
        if (last_page === 1) {
          setData(firstPageData);
          return;
        }

        // 生成剩余页面的请求Promise数组
        const pagePromises = [];
        for (let page = 2; page <= last_page; page++) {
          pagePromises.push(getJobs(page));
        }

        // 并行请求所有剩余页面
        const otherPagesRes = await Promise.all(pagePromises);
        // 合并所有页面的数据
        const allData = [
          ...firstPageData,
          ...otherPagesRes.flat(res => res.data.data.data)
        ];

        setData(allData);
      } catch (e) {
        console.log("Jobs error", e);
      }
    };

    fetchAllJobs();
  }, []);

  useEffect(() => {
    console.log(data);
  }, [data]);

  return (
    <div>
      {data.map((d) => (
        <div key={d.id} className="d-flex"> {/* 用数据唯一ID作为key更稳定 */}
          <h1>{d.id}</h1>
          <h1>{d.job_title}</h1>
        </div>
      ))}
    </div>
  );
};

export default MyTable;

方式二:递归请求下一页(灵活)

如果API的分页规则可能变化,依赖next_page_url递归请求更贴合API设计:

import React from "react";
import { useState, useEffect } from "react";
import axiosClient from "../path/to/axiosClient"; // 导入axiosClient

const MyTable = () => {
  const [data, setData] = useState([]);

  useEffect(() => {
    const fetchAllJobs = async (pagePath = "/jobs") => {
      try {
        const res = await axiosClient.get(pagePath);
        const { data: pageData, next_page_url } = res.data.data;
        
        // 合并当前页数据到总数据中
        setData(prev => [...prev, ...pageData]);

        // 如果存在下一页链接,继续请求
        if (next_page_url) {
          // 移除baseURL,只保留路径部分(因为axiosClient已配置baseURL)
          const nextPath = next_page_url.replace(axiosClient.defaults.baseURL, "");
          await fetchAllJobs(nextPath);
        }
      } catch (e) {
        console.log("Jobs error", e);
      }
    };

    fetchAllJobs();
  }, []);

  // 其余渲染代码和之前一致...
  return (
    <div>
      {data.map((d) => (
        <div key={d.id} className="d-flex">
          <h1>{d.id}</h1>
          <h1>{d.job_title}</h1>
        </div>
      ))}
    </div>
  );
};

export default MyTable;

注意事项

  • 并行请求效率高,但如果总页数过多,可能触发API频率限制,此时可考虑添加延迟或分批请求
  • 递归请求更灵活,但要注意分页页数不要过多(避免栈溢出,不过一般分页页数不会达到触发栈溢出的量级)
  • 列表渲染时建议使用数据的唯一标识(如d.id)作为key,而非数组索引,避免不必要的重渲染问题

内容的提问来源于stack exchange,提问作者Basil VJ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:06:06