react-window-infinite-loader

repository·master·Indexed 21 days ago

https://github.com/bvaughn/react-window-infinite-loader

Infinite loading utilities designed for use with the react-window virtualization library. Version 2.0.1 provides the useInfiniteLoader hook and InfiniteLoader component to manage data fetching and row loading states as users scroll through large or unknown lists. It includes configurable props such as isRowLoaded, loadMoreRows, rowCount, minimumBatchSize, and threshold to control batching and pre-fetching behavior.

Tokens
2.2K
Snippets
8
Records
8
Agent score
73%

What's inside react-window-infinite-loader

  1. Use the InfiniteLoader component

    master

    You can also use the InfiniteLoader component as a wrapper. Note that in versions 2+, the child function parameter is named onRowsRendered (formerly onItemsRendered) and the listRef parameter has been removed.

    import { InfiniteLoader } from "react-window-infinite-loader";
    
    function Example() {
      return (
        <InfiniteLoader {...props}>
          {({ onRowsRendered }) => <List onRowsRendered={onRowsRendered} {...rest} />}
        </InfiniteLoader>
      );
    }
  2. Use the useInfiniteLoader hook

    master

    The recommended way to implement infinite loading is using the useInfiniteLoader hook. This hook returns an onRowsRendered function that you pass directly to a react-window component (like List).

    import { useInfiniteLoader } from "react-window-infinite-loader";
    
    function Example() {
      const onRowsRendered = useInfiniteLoader(props);
    
      return <List onRowsRendered={onRowsRendered} {...rest} />;
    }
  3. Configure InfiniteLoader props

    master

    When using InfiniteLoader or useInfiniteLoader, you must provide specific props to manage the loading state and data fetching.

    ### Required props
    | Name | Type | Description |
    | --- | --- | --- |
    | `children` | `({ onRowsRendered: Function }) => ReactNode` | Render prop; see below for example usage. |
    | `isRowLoaded` | `(index: number) => boolean` | Function responsible for tracking the loaded state of each row. |
    | `loadMoreRows` | `(startIndex: number, stopIndex: number) => Promise<void>` | Callback to be invoked when more rows must be loaded. It should return a Promise that is resolved once all data has finished loading. |
    | `rowCount` | `number` | Number of rows in list; can be arbitrary high number if actual number is unknown. |
    
    ### Optional props
    | Name | Type | Description |
    | --- | --- | --- |
    | `minimumBatchSize` | `number` | Minimum number of rows to be loaded at a time; defaults to 10. This property can be used to batch requests to reduce HTTP requests. |
    | `threshold` | `number` | Threshold at which to pre-fetch data; defaults to 15. A threshold of 15 means that data will start loading when a user scrolls within 15 rows. |
  4. Configure InfiniteLoader Props

    master

    The Props type defines the configuration for the InfiniteLoader component. It requires functions to track loaded state and handle data fetching, along with the total row count. You can also tune batching and pre-fetching behavior using optional properties.

    Required Props

    • isRowLoaded: A function (index: number) => boolean used to track whether a specific row's data has been loaded.
    • loadMoreRows: A function (startIndex: number, stopIndex: number) => Promise<void> that is called when the threshold is met. It must return a Promise that resolves once the data loading is complete.
    • rowCount: The total number of rows in the list.

    Optional Props

    • minimumBatchSize: The minimum number of rows to be loaded at a time (defaults to 10). Useful for batching requests to reduce network overhead.
    • threshold: The number of rows from the end of the loaded range at which pre-fetching should start (defaults to 15).
    const props: Props = {
      isRowLoaded: (index) => loadedIndices.has(index),
      loadMoreRows: async (startIndex, stopIndex) => {
        await myApi.fetchRows(startIndex, stopIndex);
      },
      rowCount: 1000,
      minimumBatchSize: 20,
      threshold: 10
    };
  5. Use the useInfiniteLoader hook

    master

    The useInfiniteLoader hook manages the logic for infinite scrolling when used with react-window. It calculates which rows need to be loaded based on the current scroll position and triggers a callback to fetch more data.

    It returns an onRowsRendered callback function, which you must pass to the onItemsRendered prop of a react-window component (like FixedSizeList or VariableSizeList).

    Props

    PropTypeDefaultDescription
    isRowLoaded(index: number) => booleanRequiredA function that returns true if the row at the given index is already loaded.
    loadMoreRows(startIndex: number, stopIndex: number) => voidRequiredA function called to fetch new rows. It receives the startIndex and stopIndex of the batch that needs loading.
    rowCountnumberRequiredThe total number of rows in the list (including those not yet loaded).
    minimumBatchSizenumber10The minimum number of rows to load in a single batch.
    thresholdnumber15How many rows ahead of the current visible range to start loading.
    import { useInfiniteLoader } from 'react-window-infinite-loader';
    
    // Inside your component:
    const onRowsRendered = useInfiniteLoader({
      isRowLoaded: (index) => myData[index] !== undefined,
      loadMoreRows: (startIndex, stopIndex) => fetchRows(startIndex, stopIndex),
      rowCount: totalRows,
      minimumBatchSize: 10,
      threshold: 15,
    });
    
    // In your render:
    <FixedSizeList
      onItemsRendered={onRowsRendered}
      {...otherProps}
    />
  6. Use the InfiniteLoader component

    master

    The InfiniteLoader component manages infinite scrolling by providing an onRowsRendered callback to its children via a render prop. This callback is used to trigger data loading when specific rows are rendered within a virtualized list (typically from react-window).

    To use it, wrap your list component with InfiniteLoader and pass a function as children. This function receives an object containing onRowsRendered.

    <InfiniteLoader
      isItemLoaded={isItemLoaded}
      itemCount={itemCount}
      loadMoreItems={loadMoreItems}
    >
      {({ onRowsRendered }) => (
        <FixedSizeList
          onItemsRendered={onRowsRendered}
          {/* ... other react-window props */}
        />
      )}
    </InfiniteLoader>
  7. Use the OnRowsRendered callback type

    master

    The OnRowsRendered type defines the signature for a callback function that receives the range of indices currently being rendered. This is useful for synchronizing external state with the visible window of the list.

    It receives an Indices object containing:

    • startIndex: The index of the first row in the range.
    • stopIndex: The index of the last row in the range.
    type OnRowsRendered = (indices: { startIndex: number; stopIndex: number }) => void;