Blog>
Snippets

Managing Variable Item Heights in TanStack Virtual

Provide an example of how to handle lists with variable item heights using TanStack Virtual, ensuring smooth scrolling and performance.
import { useVirtualizer } from '@tanstack/react-virtual';
Import the useVirtualizer hook from @tanstack/react-virtual package.
const parentRef = useRef();
Create a reference for the scrolling parent container.
const rowVirtualizer = useVirtualizer({
  count: items.length,
  getScrollElement: () => parentRef.current,
  estimateSize: useCallback((index) => estimateRowHeight(index), []),
  overscan: 5,
});
Initialize the virtualizer for the list. 'items' is your data array. Use 'estimateSize' to provide an estimated size for each item based on its index which helps in handling variable item heights. 'overscan' is how many items to render outside of the visible area.
const estimateRowHeight = (index) => {
  // Logic to estimate row height
  return 50; // Example fixed height, replace with actual logic
};
Define a function to estimate the height of each row. You may need a more dynamic way to estimate depending on the item's content.
return (
  <div ref={parentRef} style={{ overflow: 'auto', height: '100vh' }}>
    <div style={{ height: `${rowVirtualizer.getTotalSize()}px`, position: 'relative' }}>
      {rowVirtualizer.getVirtualItems().map(virtualRow => (
        <div
          key={virtualRow.index}
          style={{
            position: 'absolute',
            top: 0,
            left: 0,
            width: '100%',
            height: `${virtualRow.size}px`,
            transform: `translateY(${virtualRow.start}px)`
          }}
        >
          {items[virtualRow.index]}
        </div>
      ))}
    </div>
  </div>
);
Render the virtualized list. The outer div acts as a scrolling container. The inner div's height is set to the total size calculated by the virtualizer, providing space for all items. Each item is absolutely positioned within this container based on its virtual position and size.