Creating a Virtualized Grid with Dynamic Sizes
Showcase the setup of a virtualized grid layout where each cell has dynamic content size, using TanStack Virtual's dynamic size features.
import { useVirtual } from '@tanstack/react-virtual';
import { useRef } from 'react';
Import the necessary hooks from React and the useVirtual hook from '@tanstack/react-virtual'.
const parentRef = useRef(null);
Create a ref for the grid parent container to track its scroll.
const rowVirtualizer = useVirtual({
size: 100, // Number of rows in the grid
parentRef,
estimateSize: () => 35, // Initial estimated row height
overscan: 5, // How many items to render outside of the visible area
});
Instantiate a row virtualizer with an estimated size for dynamic row heights. The `size` property defines the total count of items.
const columnVirtualizer = useVirtual({
horizontal: true,
size: 100, // Number of columns in the grid
parentRef,
estimateSize: () => 100, // Initial estimated column width
overscan: 5, // How many items to render outside of the visible area
});
Instantiate a column virtualizer for a grid that has dynamic column widths. Setting `horizontal` to true enables horizontal virtualization.
const gridStyle = {
height: `100vh`,
width: `100%`,
overflow: 'auto',
position: 'relative',
};
Define the style for the grid container, which includes setting its position to relative to position the virtualized items absolutely within it.
const renderVirtualGrid = () => (
<div ref={parentRef} style={gridStyle}>
<div style={{
height: `${rowVirtualizer.totalSize}px`,
width: `${columnVirtualizer.totalSize}px`,
position: 'relative',
}}>
{rowVirtualizer.virtualItems.map(rowVirtual => (
columnVirtualizer.virtualItems.map(columnVirtual => (
<div key={`${rowVirtual.index}-${columnVirtual.index}`} style={{
position: 'absolute',
top: `${rowVirtual.start}px`,
left: `${columnVirtual.start}px`,
height: `${rowVirtual.size}px`,
width: `${columnVirtual.size}px`,
}}>
{/* Render your content based on rowVirtual.index and columnVirtual.index */}
Item {rowVirtual.index}-{columnVirtual.index}
</div>
))
))}
</div>
</div>
);
This function renders the virtualized grid. Each cell of the grid is positioned absolutely within the parent based on its virtual position and size.