TanStack QueryのuseInfiniteQueryは無限スクロールを簡単に実装できる便利なメソッドです。
単純に実装すると、画面表示後 in view 判定を行った後に初回のデータロードを行うことになるので、画面に初期データが表示されるまでラグが発生します。
placeholderDataを使用して初期値を設定することで、画面表示時にタイムラグなしでデータを表示することが可能です。
以下はRemixでの例です。loaderで取得したデータをplaceholderDataに渡しています。
// loaderを使用してサーバーサイドでデータ取得
export const loader = async () => {
const data = await client.getList<Post>({ endpoint: "blog", queries: { limit: LIMIT } });
if (!data) {
throw new Response("Not Found", { status: 404 });
}
const res: BlogResponse = {
posts: data.contents,
totalCount: data.totalCount,
nextOffset: data.offset + LIMIT,
hasNextPage: data.offset <= data.totalCount,
};
return res;
};
export default function Index() {
const loaderData = useLoaderData<typeof loader>();
const fetchBlog = async (offset: number): Promise<BlogResponse> => {
const res = await fetch(`/blog?offset=${offset}`);
return res.json();
};
const { data, hasNextPage, fetchNextPage } = useInfiniteQuery({
queryKey: ["blog"],
queryFn: async ({ pageParam }) => await fetchBlog(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage: BlogResponse) => lastPage.nextOffset,
// loaderDataで取得した値を初期値として使用
placeholderData: {
pages: [loaderData],
pageParams: [loaderData.nextOffset],
},
});
....修正前
修正後