如何用React Query实现无限滚动(API仅返回hasNextPage标识)
用React Query实现基于hasNextPage的无限滚动(滚动到底部自动加载)
核心思路
React Query的useInfiniteQuery是处理无限滚动的适配工具,结合你的API返回的hasNextPage字段,无需总页数或总数据量,就能精准控制下一页加载逻辑。
步骤1:配置useInfiniteQuery
先定义API请求函数,再用useInfiniteQuery完成查询配置:
import { useInfiniteQuery } from '@tanstack/react-query'; // 定义API请求函数,接收当前页码参数 const fetchEvents = async ({ pageParam = 1 }) => { const response = await fetch(`/api/events?page=${pageParam}`); const data = await response.json(); return data; // 对应API返回结构:{ events: Event[], hasNextPage: boolean } }; function EventList() { const { data, fetchNextPage, hasNextPage, isFetchingNextPage, status, error, } = useInfiniteQuery({ queryKey: ['events'], // 唯一标识查询的键 queryFn: fetchEvents, // 关键逻辑:根据上一页的hasNextPage判断是否触发下一页 getNextPageParam: (lastPage, allPages) => { if (lastPage.hasNextPage) { return allPages.length + 1; // 已加载n页,下一页为n+1(页码从1开始) } return undefined; // 返回undefined表示没有下一页 }, initialPageParam: 1, // 初始页码设为1 });
步骤2:添加滚动监听逻辑
通过useEffect监听窗口滚动,当滚动接近底部时自动触发下一页加载:
useEffect(() => { const handleScroll = () => { // 判断是否滚动到接近底部(200px阈值,可根据体验调整) const isNearBottom = window.innerHeight + document.documentElement.scrollTop >= document.documentElement.offsetHeight - 200; // 满足条件才触发:有下一页、当前未在加载下一页、滚动到阈值区域 if (isNearBottom && hasNextPage && !isFetchingNextPage) { fetchNextPage(); } }; window.addEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll); }, [hasNextPage, isFetchingNextPage, fetchNextPage]);
步骤3:渲染数据与状态
合并所有页面的events数据,渲染列表并展示加载/无更多数据状态:
// 合并所有页面的events数组 const allEvents = data?.pages.flatMap(page => page.events) || []; if (status === 'loading') return <div>加载中...</div>; if (status === 'error') return <div>加载失败:{error.message}</div>; return ( <div> <ul> {allEvents.map(event => ( <li key={event.id}>{event.title}</li> // 根据你的event结构调整渲染内容 ))} </ul> {/* 下一页加载状态提示 */} {isFetchingNextPage && <div>加载更多...</div>} {/* 无更多数据时的提示 */} {!hasNextPage && allEvents.length > 0 && <div>已加载全部数据</div>} </div> ); } export default EventList;
关键细节说明
getNextPageParam:利用已加载页面数量计算下一页页码,完全适配你的API页码递增逻辑,无需额外参数。- 滚动阈值:设置提前加载的阈值,避免用户滚动到底部才开始加载,提升流畅度。
- 重复请求拦截:通过
isFetchingNextPage判断当前是否在加载下一页,防止重复触发请求。
内容的提问来源于stack exchange,提问作者Rayyan Alam
相关产品推荐
相关产品推荐

