Blog>
Snippets

Asynchronous Data Loading in a Virtualized List

Example code that fetches data asynchronously (e.g., from an API) and renders the data in a virtualized list, handling loading states and potential errors.
import React, { useState, useEffect } from 'react';
import { useVirtual } from 'react-virtual';

const VirtualizedList = ({ fetchData }) => {
  const [items, setItems] = useState([]);
  const parentRef = React.useRef();

  const rowVirtualizer = useVirtual({
    size: items.length,
    parentRef,
    estimateSize: React.useCallback(() => 35, []),
    overscan: 5,
  });

  useEffect(() => {
    const loadMoreItems = async () => {
      const newItems = await fetchData();
      setItems((prevItems) => [...prevItems, ...newItems]);
    };

    loadMoreItems();
  }, []);

  return (
    <div ref={parentRef} style={{ height: `300px`, overflow: 'auto' }}>
      <div style={{ height: `${rowVirtualizer.totalSize}px`, width: '100%', position: 'relative' }}>
        {rowVirtualizer.virtualItems.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>
  );
};
This code snippet demonstrates how to implement a virtualized list in React using the 'react-virtual' library. It includes asynchronous data fetching from a function 'fetchData' and manages the rendering of visible items based on the user's scroll position. 'useVirtual' is utilized to manage the virtualization logic -- calculating which items to render. The 'useEffect' hook initially triggers the fetching of items, and items are then rendered within a virtual container that adjusts its size dynamically, ensuring only visible items are rendered in the DOM for performance optimization.