Blog>
Snippets

Handling Dynamic Item Sizes in Virtual Scrolling

Provide a code snippet that illustrates handling dynamic item sizes within a virtualized list or grid, including how to update item size calculations on-the-fly.
import { useRef } from 'react';
import { useVirtual } from '@tanstack/react-virtual';
First, import useRef from React and useVirtual from TanStack Virtual.
const parentRef = useRef();
Create a ref for the parent container of the virtualized list.
const rowVirtualizer = useVirtual({
  size: items.length, // Number of items in the list
  parentRef, // Reference to the scrolling container
  estimateSize: useCallback(() => 50, []), // Initial estimated size
  measure: useCallback((item) => {}
  // Implement measuring logic here
  , [])
});
Initialize the virtualizer with configurations. 'estimateSize' provides an initial size estimate, while 'measure' would be used for dynamic measuring.
const measuredRef = useCallback(node => {
  if (node !== null) {
    // Assume you have a way to obtain the item's index from the node
    const index = node.dataset.index;
    // Update the item size dynamically
    rowVirtualizer.measure(index);
  }
}, [rowVirtualizer]);
Define a callback ref for dynamically measuring item sizes upon rendering. It uses the virtualizer's measure function to update each item's stored size.
// Within the component's return statement
{rowVirtualizer.virtualItems.map(virtualItem => (
  <div
    ref={measuredRef}
    key={virtualItem.key}
    style={{
      position: 'absolute',
      top: 0,
      left: virtualItem.start,
      width: '100%',
      height: `${virtualItem.size}px`
    }}
  >
    {/* Render your item content here */}
  </div>
))}
Render the virtualized items, assigning the measuredRef to each item for dynamic size adjustments. The styles position each item according to virtualized calculations.