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
相关产品推荐
相关产品推荐

