Blog>
Snippets

Implementing Infinite Scroll with TanStack Virtual

Showcase how to implement infinite scrolling in a list using TanStack Virtual, including handling asynchronous data fetching.
import { useVirtualizer } from '@tanstack/react-virtual';
Imports the useVirtualizer hook from the @tanstack/react-virtual package for virtualization.
const fetchMoreItems = async (startIndex, stopIndex) => {
  // Function to fetch more items from server
  // Replace this with your actual data fetching logic
};
Defines an async function to fetch more items based on start and stop indexes. This should be replaced with actual data fetching logic.
const ListComponent = ({ items }) => {
  const parentRef = React.useRef();

  const rowVirtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 50, // Adjust based on your row height
    overscan: 5,
  });

  useEffect(() => {
    const loadMore = async () => {
      const { start, end } = rowVirtualizer.getVirtualItemsRange();
      await fetchMoreItems(start, end);
    };

    const scrollElement = parentRef.current;
    const scrollListener = () => {
      if (scrollElement.scrollTop + scrollElement.clientHeight >= scrollElement.scrollHeight) {
        loadMore();
      }
    };

    scrollElement.addEventListener('scroll', scrollListener);
    return () => scrollElement.removeEventListener('scroll', scrollListener);
  }, [rowVirtualizer]);

  return (
    <div ref={parentRef} style={{ height: '100%', overflow: 'auto' }}>
      {rowVirtualizer.getVirtualItems().map(virtualRow => (
        <div key={virtualRow.index} style={{
          position: 'absolute',
          top: 0,
          left: 0,
          width: '100%',
          transform: `translateY(${virtualRow.start}px)`
        }}>
          {items[virtualRow.index]}
        </div>
      ))}
    </div>
  );
}
Creates a ListComponent using useVirtualizer. Integrates an infinite scroll mechanism by adding a scroll event listener to fetch more items when the user scrolls to the bottom of the list.