Web / TanStack Interview Questions
How do you combine useInfiniteQuery with useVirtualizer for an infinitely scrolling virtualised list?
This is one of the most powerful TanStack patterns: useInfiniteQuery fetches pages as the user scrolls while useVirtualizer renders only visible DOM nodes — together they handle millions of rows with minimal memory.
<script setup lang="ts"> import { ref, computed, watchEffect } from "vue" import { useInfiniteQuery } from "@tanstack/vue-query" import { useVirtualizer } from "@tanstack/vue-virtual" const parentRef=ref<HTMLDivElement|null>(null) const { data, fetchNextPage, hasNextPage, isFetchingNextPage }=useInfiniteQuery({ queryKey: ["posts","infinite"], queryFn: ({pageParam})=>fetchPosts({page:pageParam}), initialPageParam: 0, getNextPageParam: last=>last.nextPage??undefined, }) const allRows=computed(()=>data.value?data.value.pages.flatMap(p=>p.rows):[]) const virt=useVirtualizer({ // +1 sentinel row triggers next-page fetch when it enters viewport get count(){ return hasNextPage.value?allRows.value.length+1:allRows.value.length }, getScrollElement: ()=>parentRef.value, estimateSize: ()=>72, overscan: 5, }) const vItems=computed(()=>virt.value.getVirtualItems()) watchEffect(()=>{ const last=vItems.value.at(-1) if(!last) return if(last.index>=allRows.value.length-1 && hasNextPage.value && !isFetchingNextPage.value) fetchNextPage() }) </script>
More Related questions...