Blog>
Snippets

Implementing Lazy Loading in TanStack Virtual Tables

Demonstrate how to implement lazy loading of data in a virtualized table created with TanStack Virtual, focusing on fetching and rendering data as the user scrolls, to enhance performance with large datasets.
import { useVirtualizer } from '@tanstack/react-virtual';
Imports the useVirtualizer hook from TanStack Virtual, which is essential for creating virtualized tables.
import React, { useRef, useState, useEffect } from 'react';
Imports necessary React hooks for managing state and effects.
const fetchMoreRows = async (from, to) => {
  // Replace this with your data fetching logic
  // This function should return a new set of data based on the range passed
};
Defines an asynchronous function to fetch more rows of data. This is a placeholder and should be replaced with actual data fetching logic.
const VirtualizedTable = () => {
  const parentRef = useRef();
  const [rows, setRows] = useState([]);

  const rowVirtualizer = useVirtualizer({
    count: rows.length + 1, // +1 for the loading indicator
    getScrollElement: () => parentRef.current,
    estimateSize: () => 35, // Adjust based on your row height
    overscan: 5,
  });

  useEffect(() => {
    const loadMore = async () => {
      const startIndex = rows.length;
      const endIndex = startIndex + 20; // Determine how many rows you want to load per batch
      const newRows = await fetchMoreRows(startIndex, endIndex);
      setRows((currentRows) => [...currentRows, ...newRows]);
    };

    loadMore();
  }, [rows.length]);

  return (
    <div ref={parentRef} style={{ overflow: 'auto', height: '100vh' }}>
      <div style={{ height: `${rowVirtualizer.getTotalSize()}px`, position: 'relative' }}>
        {rowVirtualizer.getVirtualItems().map((virtualRow) => (
          <div
            key={virtualRow.key}
            style={{
              position: 'absolute',
              top: 0,
              left: 0,
              width: '100%',
              transform: `translateY(${virtualRow.start}px)`,
              height: `${virtualRow.size}px`,
            }}
          >
            {rows[virtualRow.index] || 'Loading...'}
          </div>
        ))}
      </div>
    </div>
  );
};
Creates a VirtualizedTable component. Initializes a row virtualizer with the useVirtualizer hook, and dynamically fetches more data as needed. The virtualizer updates the rendered rows based on user scrolling to achieve lazy loading.
export default VirtualizedTable;
Exports the VirtualizedTable component for use in other parts of the application.