https://github.com/bvaughn/react-window-infinite-loader
InfiniteLoader component inspired by react-virtualized but for use with react-window
https://github.com/bvaughn/react-window-infinite-loader
Last synced: 8 months ago
JSON representation
InfiniteLoader component inspired by react-virtualized but for use with react-window
- Host: GitHub
- URL: https://github.com/bvaughn/react-window-infinite-loader
- Owner: bvaughn
- License: mit
- Created: 2018-12-10T00:00:06.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2025-01-25T02:41:22.000Z (12 months ago)
- Last Synced: 2025-05-11T13:39:43.837Z (8 months ago)
- Language: JavaScript
- Size: 118 KB
- Stars: 939
- Watchers: 9
- Forks: 46
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.MD
Awesome Lists containing this project
- awesome-list - react-window-infinite-loader - virtualized but for use with react-window | bvaughn | 637 | (JavaScript)
README
# react-window-infinite-loader
> InfiniteLoader component inspired by react-virtualized but for use with [react-window](https://github.com/bvaughn/react-window/)
### If you like this project, 🎉 [become a sponsor](https://github.com/sponsors/bvaughn/) or ☕ [buy me a coffee](http://givebrian.coffee/)
## Install
```bash
# 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` | 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`.
```js
// 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;
{({ onItemsRendered, ref }) => (
)}
```
[Try it on Code Sandbox](https://codesandbox.io/s/5wqo7z2np4)
## 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:
```jsx
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
{content};
};
return (
{({ onItemsRendered, ref }) => (
{Item}
)}
);
}
```
[Try it on Code Sandbox](https://codesandbox.io/s/x70ly749rq)
## 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.
```jsx
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 (
{({ onItemsRendered, ref }) => (
// ...
)}
);
}
```
[Try it on Code Sandbox](https://codesandbox.io/embed/lucid-tree-7wnrq)
## License
MIT © [bvaughn](https://github.com/bvaughn)