Skip to content

Navigation Menu

Sign in
Sign up

Repository files navigation

react-window-infinite-loader

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

Install

# Yarn
yarn add react-window-infinite-loader
# NPM
npm install --save react-window-infinite-loader

Documentation

Name Type Description
children ({ onItemsRendered: Function, ref: React$Ref }) => React$Node Render prop. See below for example usage.
isItemLoaded (index: number) => boolean Function responsible for tracking the loaded state of each item.
itemCount number Number 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 ?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.

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

About

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

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

AltStyle によって変換されたページ (->オリジナル) /