Skip to content

onderonur/react-infinite-scroll-hook

Repository files navigation

react-infinite-scroll-hook

All Contributors

This is a hook to create infinite scroll components!
Live demo is here.

Before v4, useInfiniteScroll hook would basically check the DOM with an interval and look at the distance between the bottom of your "infinite" component and the bottom of the window. This was a simple solution. But it had its difficulties. It was not so easy to change the layout of your "infinite" component (like creating a chat message box with inverted scrolling etc). It was a requirement to modify the package based on each different use case.

And also, checking the DOM with an interval by using setInterval wasn't a sophisticated solution. It was enough, but it had it's limits. With v4, we migrated to use IntersectionObserver and created a much more flexible API to support different design. Basically, now we have a little bit more inversion of control.

Basically, we need to set a sentry component to trigger infinite loading. When sentry becomes visible on the screen, or it comes near (based on our config of course), it triggers infinite loading all with the help of IntersectionObserver. So, we can make components with different layouts like an inverted scrolling chat message box, horizontal scrolling etc.

Note: This package uses IntersectionObserver under the hood. You might want to check the browser compatibility from here and if you want to support older browsers, you might need to use a polyfill.

If you want to use the older version which is using setInterval, you can find it here.

Installation

npm install react-infinite-scroll-hook

Basic Usage

import useInfiniteScroll from 'react-infinite-scroll-hook'; function InfiniteList({}) { const [items, setItems] = useState([]); const [hasNextPage, setHasNextPage] = useState(); const [loading, setLoading] = useState(false); /// ... function handleLoadMore() { setLoading(true); // Some API call to fetch the next page loadNextPage(endCursor, pageSize).then((newPage) => { setLoading(false); setHasNextPage(newPage.hasNextPage); setItems([...items, newPage.items]); }); } const infiniteRef = useInfiniteScroll({ loading, hasNextPage, onLoadMore: handleLoadMore, scrollContainer, }); // ... return ( <List ref={infiniteRef}> {items.map((item) => ( <ListItem key={item.key}>{item.value}</ListItem> ))} {loading && <ListItem>Loading...</ListItem>} </List> ); }

Props

  • loading: Some sort of "fetching" info of the request.
  • hasNextPage: If the list has more items to load.
  • onLoadMore: The callback function to execute when the threshold is exceeded.
  • threshold: Maximum distance to bottom of the window/parent to trigger the callback. Default is 150.
  • checkInterval: Frequency to check the dom. Default is 200.
  • scrollContainer: May be "window" or "parent". Default is "window". If you want to use a scrollable parent for the infinite list, use "parent".

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Eugene Fidelin

💻

Evan Cater

📖

This project follows the all-contributors specification. Contributions of any kind welcome!