1.0.10 • Published 5 months ago

react-window-infinite-loader v1.0.10

Weekly downloads
87,990
License
MIT
Repository
github
Last release
5 months ago

react-window-infinite-loader

InfiniteLoader component inspired by react-virtualized but for use with react-window

If you like this project, 🎉 become a sponsor or ☕ buy me a coffee

Install

# Yarn
yarn add react-window-infinite-loader

# NPM
npm install --save react-window-infinite-loader

Documentation

NameTypeDescription
children({ onItemsRendered: Function, ref: React$Ref }) => React$NodeRender prop. See below for example usage.
isItemLoaded(index: number) => booleanFunction responsible for tracking the loaded state of each item.
itemCountnumberNumber of rows in list; can be arbitrary high number if actual number is unknown.
loadMoreItems(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.
minimumBatchSize?numberMinimum 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?numberThreshold 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.

Example usage

The snippet below shows a basic example of how the InfiniteLoader can be used to wrap either a FixedSizeList or VariableSizeList from react-window.

// This value is arbitrary.
// If you know the size of your remote data, you can provide a real value.
// You can also increase this value gradually (as shown in the example below).
const itemCount = 1000;

<InfiniteLoader
  isItemLoaded={isItemLoaded}
  itemCount={itemCount}
  loadMoreItems={loadMoreItems}
>
  {({ onItemsRendered, ref }) => (
    <FixedSizeList
      itemCount={itemCount}
      onItemsRendered={onItemsRendered}
      ref={ref}
      {...otherListProps}
    />
  )}
</InfiniteLoader>

Try it on Code Sandbox

Creating an infinite loading list

The InfiniteLoader component was created to help break large data sets down into chunks that could be just-in-time loaded as they were scrolled into view. It can also be used to create infinite loading lists (e.g. Facebook or Twitter). Here's a basic example of how you might implement that:

function ExampleWrapper({
  // Are there more items to load?
  // (This information comes from the most recent API request.)
  hasNextPage,

  // Are we currently loading a page of items?
  // (This may be an in-flight flag in your Redux store for example.)
  isNextPageLoading,

  // Array of items loaded so far.
  items,

  // Callback function responsible for loading the next page of items.
  loadNextPage
}) {
  // If there are more items to be loaded then add an extra row to hold a loading indicator.
  const itemCount = hasNextPage ? items.length + 1 : items.length;

  // Only load 1 page of items at a time.
  // Pass an empty callback to InfiniteLoader in case it asks us to load more than once.
  const loadMoreItems = isNextPageLoading ? () => {} : loadNextPage;

  // Every row is loaded except for our loading indicator row.
  const isItemLoaded = index => !hasNextPage || index < items.length;

  // Render an item or a loading indicator.
  const Item = ({ index, style }) => {
    let content;
    if (!isItemLoaded(index)) {
      content = "Loading...";
    } else {
      content = items[index].name;
    }

    return <div style={style}>{content}</div>;
  };

  return (
    <InfiniteLoader
      isItemLoaded={isItemLoaded}
      itemCount={itemCount}
      loadMoreItems={loadMoreItems}
    >
      {({ onItemsRendered, ref }) => (
        <FixedSizeList
          itemCount={itemCount}
          onItemsRendered={onItemsRendered}
          ref={ref}
          {...props}
        >
          {Item}
        </FixedSizeList>
      )}
    </InfiniteLoader>
  );
}

Try it on Code Sandbox

Advanced usage

Some use cases require cached items to be reset. For example, after a list has been sorted, previously cached items may be invalid. You can let InfiniteLoader know that it needs to reload cached items by calling the resetloadMoreItemsCache method.

function ExampleWrapper({
  // ...
  sortOrder,
}) {
  // We create a reference for the InfiniteLoader
  const infiniteLoaderRef = useRef(null);
  const hasMountedRef = useRef(false);

  // Each time the sort prop changed we called the method resetloadMoreItemsCache to clear the cache
  useEffect(() => {
    // We only need to reset cached items when "sortOrder" changes.
    // This effect will run on mount too; there's no need to reset in that case.
    if (hasMountedRef.current) {
      if (infiniteLoaderRef.current) {
        infiniteLoaderRef.current.resetloadMoreItemsCache();
      }
    }
    hasMountedRef.current = true;
  }, [sortOrder]);
  
  // ...

  // We passed down the ref to the InfiniteLoader component
  return (
    <InfiniteLoader
      ref={infiniteLoaderRef}
      isItemLoaded={isItemLoaded}
      itemCount={itemCount}
      loadMoreItems={loadMoreItems}
    >
      {({ onItemsRendered, ref }) => (
        // ...
      )}
    </InfiniteLoader>
  );
}

Try it on Code Sandbox

License

MIT © bvaughn

@invisionag/components@mateuszmigas/dropdown@open-raven/react-styleguidekhodroinja-ui-coremoneko.consolenotes-fwreact-highlightable-datasheetmdlinx-smartestdoc@infinitebrahmanuniverse/nolb-react-wi@oerlikon/ui@compassdigital/compassdigital.components.distilr@everything-registry/sub-chunk-2624react-publishable-component-sunilwhat-a-dragsushiwebvehicle-list-lib@cromwell/admin-panel@concrete-design/table@dalmo/sanity-plugin-media@coreyward/sanity-plugin-media@contentstack/venus-components@caisy/league@romaingrx/label-studio-mirrorjoule-cc-swapish-uilatitude-flexportprox-uisunmoon-working-componentsuhnoxi-music-webuhnoxi-music-web-buildtnpulse-react-twemoji-picker@ainias42/react-bootstrap-mobile@anyvision/anv-ui-components@aics/fms-file-explorer-core@adviseinc-motor-js/components@beatchainmusic/ui@carlospence/react-fluid-table@coformatique/ui@deriv/p2p@darren-z-m-lin/trojan-web-manager-clientunbxd-react-components@economic/gaudi@economic/taco@habx/ui-table@gruzf/widget@hdream/uniswap-pool@flowfact/ui-components@elliemae/ds-legacy-shuttle@elliemae/ds-legacy-mobile@gaut/ui@goto-company/apsara@frontapp/ui-kit@kyburz/kdesign-system@krowdy/kds-views@krowdy-ui/views@lezztable-demo/react@itwin/changed-elements-react@motor-js/components@nexray/app@nexusui/components@mrtujiawei/react-components@elliemae/ds-mobile@mateuszmigas/react-dropdown@mnemotix/koncept-core@inv3rse/design-system@jayjonesdev/react-material-ui-library@illa-public/resource-generator@rangodev/ui@rango-test/ui@rafty/ui@procore/core-react@paprika/data-table@simspace/monorailmui-data-datagridmycel-widgetminta-platformmig-schema-tablemetadata-reactonekijs-uisdk-chat-widgetsdk-chat-widget-testselect-muireact-components-bundlereact-formbuilder-v2redux-connected-componentsreact-infinite-virtual-treereact-native-ridge-listsg-mobilesleek-uireact-simple-infinite-loadingreact-table-flash-uireact-window-infinite-scroll-simplereact-window-pull-refreshreact-unifiedsimbrarygm_static_x_mesilla-builderimuiinfinite-nftinforiver-enterprise
1.0.10

5 months ago

1.0.9

2 years ago

1.0.8

3 years ago

1.0.7

4 years ago

1.0.6

4 years ago

1.0.5

6 years ago

1.0.4

6 years ago

1.0.3

7 years ago

1.0.2

7 years ago

1.0.1

7 years ago

1.0.0

7 years ago