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

React组件中GitHub GraphQL分页:如何获取第31-40条数据?

实现GraphQL游标分页获取指定范围数据

问题分析

你当前的handlePageClick逻辑存在核心错误:GraphQL的游标(cursor)是服务端生成的字符串标识,并非可计算的数字,不能通过startCursor + (page-1)*10这种方式拼接生成。要获取第31-40条数据(即第4页,每页10条),必须基于前一页的endCursor来设置after参数,而非自行计算。

正确实现方案

核心思路是维护一个游标历史数组,记录每一页对应的结束游标,跳转到任意页时直接取用对应游标值即可:

1. 组件状态管理

在React组件中添加必要的状态,用于跟踪页码、游标历史、分页信息及数据:

import { useState, useEffect } from 'react';
import { ApolloQueryResult } from '@apollo/client';
// 假设已导入searchRepositories查询及相关类型定义

const RepositorySearch = () => {
  const [searchTerm, setSearchTerm] = useState('react');
  const [currentPage, setCurrentPage] = useState(1);
  // 游标历史:索引对应页码,cursorHistory[n]表示第n页的endCursor(用于请求第n+1页)
  const [cursorHistory, setCursorHistory] = useState<string[]>([]);
  const [pageInfo, setPageInfo] = useState<{
    endCursor?: string;
    hasNextPage: boolean;
    hasPreviousPage: boolean;
  }>({ hasNextPage: false, hasPreviousPage: false });
  const [repositories, setRepositories] = useState<any[]>([]);

2. 初始加载第一页

首次渲染时请求第一页数据,无需传入after参数:

useEffect(() => {
  const fetchFirstPage = async () => {
    const { data }: ApolloQueryResult<any> = await searchRepositories({
      variables: { searchTerm, first: 10 }
    });
    if (data?.search) {
      setRepositories(data.search.edges.map((edge: any) => edge.node));
      setPageInfo(data.search.pageInfo);
      // 第一页的endCursor存入索引1位置,用于请求第二页
      setCursorHistory(['', data.search.pageInfo.endCursor]);
    }
  };
  fetchFirstPage();
}, [searchTerm]);

3. 分页点击逻辑实现

修改handlePageClick,根据目标页码从游标历史中获取对应的after参数:

const handlePageClick = async (page: number): Promise<void> => {
  // 第一页不需要after参数,其他页取对应前一页的endCursor
  const afterCursor = page === 1 ? undefined : cursorHistory[page - 1];
  
  const { data }: ApolloQueryResult<any> = await searchRepositories({
    variables: { searchTerm, first: 10, after: afterCursor }
  });

  if (data?.search) {
    setRepositories(data.search.edges.map((edge: any) => edge.node));
    setPageInfo(data.search.pageInfo);
    setCurrentPage(page);
    
    // 更新游标历史:若当前页的endCursor未存入则添加
    if (!cursorHistory[page]) {
      setCursorHistory(prev => {
        const newHistory = [...prev];
        newHistory[page] = data.search.pageInfo.endCursor;
        return newHistory;
      });
    }
  }
};

4. 直接获取第31-40条数据

当需要获取第31-40条数据时,直接调用handlePageClick(4)即可:

  • 此时afterCursor会取cursorHistory[3](即第3页的endCursor),服务端会返回该游标之后的10条数据,正好对应第31-40条。

关键注意事项

  • 禁止自行计算游标:游标是服务端生成的唯一标识,格式由服务端定义(多为Base64编码字符串),无法通过数字运算生成。
  • 维护游标历史:支持任意页码的直接跳转,无需逐页请求到目标页。
  • 处理边界场景:比如第一页无需after参数、最后一页无法继续前进等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:33:15