如何使用无限查询(TanStack Query)进行无限滚动
这是您的帖子翻译成英文:
在这篇文章中,我将教您如何使用 tanstack 查询(特别是无限查询)实现无限滚动。我们将使用 vite 创建照片源并设置无限滚动。首先,打开终端并运行以下命令来克隆具有基本配置的项目:
git clone --branch start https://github.com/davi-rezende/photos-feed.git cd photos-feed npm i
一切就绪!现在,让我们使用 tanstack 查询库实现无限滚动功能。使用以下命令安装它:
npm i @tanstack/react-query npm i axios
在 app.tsx 文件中,您会看到代码如下所示:
首先,我们将使用 useinfinitequery 替换 useeffect,useinfinitequery 负责管理无限请求。我们必须为其提供两个属性:querykey 和 queryfn,如下所示:
const { data, isloading, fetchnextpage, isfetchingnextpage, isfetching, hasnextpage } = useinfinitequery({ queryfn: fetchphotos, querykey: ['photos'], initialpageparam: 1, getnextpageparam: (lastpage) => { return lastpage.nextpage } })
各参数说明:
- queryfn:负责返回我们请求数据的函数;它接收当前页面作为参数。
- querykey:充当请求的标识符,也充当依赖项数组。每次您在其中传递的变量发生变化时,useinfinitequery 都会自动重新获取。
- initialpageparam: 初始默认值。
- getnextpageparam:接收 queryfn 函数返回的所有内容,并且必须返回要请求的下一个页码。
我们需要修改 fetchphotos 函数:
async function fetchphotos({ pageparam }: { pageparam: number }) { const response = await api.get<imagedata[]>('/photos', { params: { page: pageparam, per_page: 5, } }) return { data: response.data, nextpage: pageparam + 1 } }
useinfinitequery 钩子返回页面中的数据,因此我们的渲染会略有变化:
<main classname="h-screen w-screen bg-zinc-950 flex flex-col gap-6 p-6 items-center text-white overflow-auto"> {isloading ? 'loading...' : ( <> {data?.pages.map((group, i) => ( <div classname="flex flex-col gap-6" key={i}> {group.data.map(({ id, urls }) => ( @@##@@ ))} </div> ))} <div> <button onclick={() => fetchnextpage()} disabled={!hasnextpage || isfetchingnextpage} > {isfetchingnextpage ? 'loading more...' : hasnextpage ? 'load more' : 'nothing more to load'} </button> </div> <div>{isfetching && !isfetchingnextpage ? 'fetching...' : null}</div> </> )} </main>
现在,每次用户到达滚动末尾并单击“加载更多”按钮时,数据都会自动附加。
要在用户到达滚动末尾时获取下一页而不需要单击按钮,只需添加以下函数:
function handlescroll(event: uievent<htmlelement>) { const { scrolltop, clientheight, scrollheight } = event.currenttarget if (scrolltop + clientheight >= scrollheight) { fetchnextpage() } }
并在包装列表的 div 中添加 onscroll 事件,并调用那里的函数。完毕!现在,每次用户滚动到末尾时,都会自动加载新数据。
最后,您的代码应如下所示:
import { useInfiniteQuery } from "@tanstack/react-query" import { UIEvent } from "react" import { api } from "./lib/api" type ImageData = { id: string, urls: { regular: string } } export function Home() { async function fetchPhotos({ pageParam }: { pageParam: number }) { const response = await api.get<ImageData[]>('/photos', { params: { page: pageParam, per_page: 5, } }) return { data: response.data, nextPage: pageParam + 1 } } const { data, isLoading, fetchNextPage, isFetchingNextPage, isFetching, hasNextPage } = useInfiniteQuery({ queryFn: fetchPhotos, queryKey: ['photos'], initialPageParam: 1, getNextPageParam: (lastPage) => { return lastPage.nextPage } }) function handleScroll(event: UIEvent<HTMLElement>) { const { scrollTop, clientHeight, scrollHeight } = event.currentTarget if (scrollTop + clientHeight >= scrollHeight) { fetchNextPage() } }; return ( <main className="h-screen w-screen bg-zinc-950 flex flex-col gap-6 p-6 items-center text-white overflow-auto" onScroll={handleScroll}> {isLoading ? 'Loading...' : ( <> {data?.pages.map((group, i) => ( <div className="flex flex-col gap-6" key={i}> {group.data.map(({ id, urls }) => ( @@##@@ ))} </div> ))} <div> <button onClick={() => fetchNextPage()} disabled={!hasNextPage || isFetchingNextPage} > {isFetchingNextPage ? 'Loading more...' : hasNextPage ? 'Load More' : 'Nothing more to load'} </button> </div> <div>{isFetching && !isFetchingNextPage ? 'Fetching...' : null}</div> </> )} </main> ) }
谢谢!
以上就是如何使用无限查询(TanStack Query)进行无限滚动的详细内容,更多请关注其它相关文章!