这是您的帖子翻译成英文:
在这篇文章中,我将教您如何使用 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 } })
我们需要修改 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 }) => ( <img className="aspect-square rounded-md h-[550px] object-cover" src={urls.regular} key={id} /> ))} </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 }) => ( <img className="aspect-square rounded-md h-[550px] object-cover" src={urls.regular} key={id} /> ))} </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)进行无限滚动的详细内容。更多信息请关注PHP中文网其他相关文章!