Waka blog.

TanStack QueryのuseInfiniteQueryに初期値を設定する

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], 
    },
  });
....

修正前

修正後