react-query useInfiniteQuery分页异常求助:pageIndex不递增致数据重复
React Query useInfiniteQuery pageIndex 始终为0 导致数据重复的解决方案
问题原因分析
你的代码存在两个关键问题,导致pageIndex无法正常递增:
fetchPosts参数传递错误:fetchPosts定义的参数是(key, pageIndex = 0),但在useInfiniteQuery的查询函数中,你只传递了pageIndex作为第一个参数,导致fetchPosts内部的pageIndex始终取默认值0。查询函数参数与调用不匹配:
useInfiniteQuery的查询函数接收包含pageIndex的对象,但调用fetchPosts时未正确传递key参数,使得参数顺序错乱,最终offset一直为0*10=0,每次都重复获取前10条数据。
解决方案
步骤1:修正参数传递逻辑
你可以直接优化fetchPosts,去掉未使用的key参数,让它只接收pageIndex:
const fetchPosts = async (pageIndex = 0) => { const offset = pageIndex * PAGE_LIMIT; try { const { data } = await axios.get(`/posts`, { params: { offset: offset, limit: PAGE_LIMIT }, }); return data; } catch (err) { console.log(err); } };
步骤2:确保查询函数正确传参
在useInfiniteQuery中,直接将解构出的pageIndex传给fetchPosts:
useInfiniteQuery("/posts", ({ pageIndex = 0 }) => fetchPosts(pageIndex), { getNextPageParam: (lastPage, allPages) => { return lastPage.length ? allPages.length : undefined; }, });
你的getNextPageParam逻辑是正确的:当最后一页有数据时,返回allPages.length作为下一页的pageIndex,确保下一次请求的offset是正确的分页起始值。
修改后的完整前端代码
import React from "react"; import { useRef, useCallback} from "react"; import axios from "axios"; import { Link } from "react-router-dom"; import { useInfiniteQuery } from "react-query"; const PAGE_LIMIT = 10; const fetchPosts = async (pageIndex = 0) => { const offset = pageIndex * PAGE_LIMIT; try { const { data } = await axios.get(`/posts`, { params: { offset: offset, limit: PAGE_LIMIT }, }); return data; } catch (err) { console.log(err); } }; const Home = () => { const { fetchNextPage, hasNextPage, isFetchingNextPage, data, status, error, } = useInfiniteQuery("/posts", ({ pageIndex = 0 }) => fetchPosts(pageIndex), { getNextPageParam: (lastPage, allPages) => { return lastPage.length ? allPages.length : undefined; }, }); const intObserver = useRef(); const lastPostRef = useCallback( (post) => { if (isFetchingNextPage) return; if (intObserver.current) intObserver.current.disconnect(); intObserver.current = new IntersectionObserver((posts) => { if (posts[0].isIntersecting && hasNextPage) { console.log("We are near the last post!"); fetchNextPage(); } }); if (post) intObserver.current.observe(post); }, [isFetchingNextPage, fetchNextPage, hasNextPage] ); if (status === "error") return <p className="center">Error: {error.message}</p>; const content = data?.pages.map((pg) => { return pg.map((post, i) => { if (pg.length === i + 1) { return ( <Link ref={lastPostRef} className="link" to={`/post/${post.id}`}> <div className="post" key={post.id}> <p> {post.title}</p> <p> {post.content}</p> </div> </Link> ); } return ( <Link className="link" to={`/post/${post.id}`}> <div className="post" key={post.id}> <p> {post.title}</p> <p> {post.content}</p> </div> </Link> ); }); }); return ( <div> <div className="home"> <div className="container"> <div className="posts"> {content} {isFetchingNextPage && ( <p className="center">Loading More Posts...</p> )} <p className="center"> <a href="#top">Back to Top</a> </p> </div> </div> </div> </div> ); }; export default Home;
验证效果
修改完成后,后端控制台打印的offset会依次为0、10、20...,每次请求都会获取新的分页数据,不会出现重复内容。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

