What is react-infinite-scroller?
The react-infinite-scroller package provides a simple way to implement infinite scrolling in React applications. It allows you to load more content as the user scrolls down the page, which is useful for displaying large lists of data without overwhelming the user or the browser.
What are react-infinite-scroller's main functionalities?
Basic Infinite Scrolling
This code demonstrates a basic implementation of infinite scrolling using the react-infinite-scroller package. It initializes a list of items and appends more items to the list as the user scrolls down. The `loadMore` function is called to fetch more items, and the `hasMore` state determines if more items should be loaded.
import React, { Component } from 'react';
import InfiniteScroll from 'react-infinite-scroller';
class InfiniteScrollExample extends Component {
state = {
items: Array.from({ length: 20 }),
hasMore: true
};
loadMore = () => {
if (this.state.items.length >= 100) {
this.setState({ hasMore: false });
return;
}
setTimeout(() => {
this.setState({
items: this.state.items.concat(Array.from({ length: 20 }))
});
}, 1500);
};
render() {
return (
<InfiniteScroll
pageStart={0}
loadMore={this.loadMore}
hasMore={this.state.hasMore}
loader={<div className="loader" key={0}>Loading ...</div>}
>
{this.state.items.map((_, index) => (
<div key={index} style={{ height: 50, border: '1px solid black' }}>
Item {index + 1}
</div>
))}
</InfiniteScroll>
);
}
}
export default InfiniteScrollExample;
Other packages similar to react-infinite-scroller
react-virtualized
react-virtualized is a library for efficiently rendering large lists and tabular data. It provides a set of components for windowing, which means only rendering the visible items in a list to improve performance. Unlike react-infinite-scroller, react-virtualized focuses on performance optimization for large datasets by virtualizing the DOM.
react-window
react-window is a lightweight alternative to react-virtualized for rendering large lists and tabular data. It offers similar functionality with a smaller footprint and simpler API. Like react-virtualized, it focuses on performance by only rendering visible items, but it is more lightweight and easier to use.
react-infinite
react-infinite is another library for implementing infinite scrolling in React applications. It provides a simple API for loading more content as the user scrolls. While similar to react-infinite-scroller, react-infinite offers more customization options for handling infinite scrolling behavior.
React Infinite Scroller
Infinitely load a grid or list of items in React. This component allows you to create a simple, lightweight infinite scrolling page or element by supporting both window and scrollable elements.
- ⏬ Ability to use window or a scrollable element
- 📏 No need to specify item heights
- 💬 Support for "chat history" (reverse) mode
- ✅ Fully unit tested and used in hundreds of production sites around the
world!
- 📦 Lightweight alternative to other available React scroll libs ~ 2.2KB
minified & gzipped
Installation
npm install react-infinite-scroller --save
yarn add react-infinite-scroller
How to use
import InfiniteScroll from 'react-infinite-scroller';
Window scroll events
<InfiniteScroll
pageStart={0}
loadMore={loadFunc}
hasMore={true || false}
loader={<div className="loader" key={0}>Loading ...</div>}
>
{items}
</InfiniteScroll>
DOM scroll events
<div style="height:700px;overflow:auto;">
<InfiniteScroll
pageStart={0}
loadMore={loadFunc}
hasMore={true || false}
loader={<div className="loader" key={0}>Loading ...</div>}
useWindow={false}
>
{items}
</InfiniteScroll>
</div>
Custom parent element
You can define a custom parentNode
element to base the scroll calulations on.
<div style="height:700px;overflow:auto;" ref={(ref) => this.scrollParentRef = ref}>
<div>
<InfiniteScroll
pageStart={0}
loadMore={loadFunc}
hasMore={true || false}
loader={<div className="loader" key={0}>Loading ...</div>}
useWindow={false}
getScrollParent={() => this.scrollParentRef}
>
{items}
</InfiniteScroll>
</div>
</div>
Props
Name | Required | Type | Default | Description |
---|
children | Yes | Node | | Anything that can be rendered (same as PropType's Node) |
loadMore | Yes | Function | | A callback when more items are requested by the user. Receives a single parameter specifying the page to load e.g. function handleLoadMore(page) { /* load more items here */ } } |
element | | Component | 'div' | Name of the element that the component should render as. |
hasMore | | Boolean | false | Whether there are more items to be loaded. Event listeners are removed if false . |
initialLoad | | Boolean | true | Whether the component should load the first set of items. |
isReverse | | Boolean | false | Whether new items should be loaded when user scrolls to the top of the scrollable area. |
loader | | Component | | A React component to render while more items are loading. The parent component must have a unique key prop. |
pageStart | | Number | 0 | The number of the first page to load, With the default of 0 , the first page is 1 . |
getScrollParent | | Function | | Override method to return a different scroll listener if it's not the immediate parent of InfiniteScroll. |
threshold | | Number | 250 | The distance in pixels before the end of the items that will trigger a call to loadMore . |
useCapture | | Boolean | false | Proxy to the useCapture option of the added event listeners. |
useWindow | | Boolean | true | Add scroll listeners to the window, or else, the component's parentNode . |
Troubleshooting
Double or non-stop calls to loadMore
If you experience double or non-stop calls to your loadMore
callback, make
sure you have your CSS layout working properly before adding this component in.
Calculations are made based on the height of the container (the element the
component creates to wrap the items), so the height of the container must equal
the entire height of the items.
.my-container {
overflow: auto;
}
Some people have found success using react-infinite-scroll-component.
But you should just add an isLoading
prop!
This component doesn't make any assumptions about what you do in terms of API
calls. It's up to you to store whether you are currently loading items from an
API in your state/reducers so that you don't make overlapping API calls.
loadMore() {
if(!this.state.isLoading) {
this.props.fetchItems();
}
}