英語に翻訳された投稿は次のとおりです:
この投稿では、TanStack クエリ、特に Infinity クエリを使用して無限スクロールを実装する方法を説明します。 Vite で写真フィードを作成し、無限スクロールを設定します。まず、ターミナルを開き、次のコマンドを実行して、基本構成でプロジェクトのクローンを作成します。
git clone --branch start https://github.com/DAVI-REZENDE/photos-feed.git cd photos-feed npm i
準備完了です!次に、TanStack Query ライブラリを使用して無限スクロール機能を実装しましょう。以下のコマンドでインストールします:
npm i @tanstack/react-query npm i axios
App.tsx ファイルでは、コードが次のようになっていることがわかります。
まず、useEffect を useInfiniteQuery (無限リクエストの管理を担当するフック) に置き換えます。次のように、queryKey と queryFn という 2 つのプロパティを指定する必要があります。
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 クエリ) を使用して無限スクロールを行う方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。