Yashar Habibi
Yashar Habibi

Reputation: 1020

“react-infinite-scroll-component” Stopped working after one call (loadMore only gets called once)

I use the react-infinite-scroll-component library for pagination,but even though hasMore is true, loadMore is called once.

     <InfiniteScroll
      dataLength={100}
      pullDownToRefreshThreshold={50}
      next={loadMoreConversation}
      scrollableTarget="scrollableDiv"
      hasMore={true}
      loader={<h4>Loading...</h4>}
    >
      <ChatItemList
        chatItems={chatItems}
        isInDeleteMode={deleteActive}
        onBottomDrawerHandler={onBottomDrawerHandler}
      />
    </InfiniteScroll>

Please help me with this, What am I doing wrong?

Upvotes: 17

Views: 16292

Answers (2)

Tom
Tom

Reputation: 16276

This is a React Query useInfiniteQuery() example, assuming you have:

data: {
  pages: [
    {/*a page*/
      results:[
        {/*an item*/
          /*...*/
        }
      ]
    }
  ]
}

Set your dataLength this way:

const {isSuccess, 
       isLoading, 
       isError, 
       data, 
       error, 
       hasNextPage, 
       fetchNextPage, 
       isFetchingNextPage
      } = useInfiniteQuery(
        path /*your query path here*/,
        fetchFn /*your fetch function here*/);
return <div>
    {isError && <div>Error! {error?.message}</div>}
    {isLoading && <div>Loading...</div>}
    {isSuccess && data?.pages && (
        <div>
            <ListHeader isFetching={isFetchingNextPage} data={data}/>
            <InfiniteScroll
                dataLength={data.pages.reduce((acc, page) => acc + page.results.length, 0)}
                next={fetchNextPage}
                hasMore={hasNextPage}
                loader={<div>Loading...</div>}
                endMessage={<p>- You have seen it all -</p>}
            >
                {data.pages.map((page, i)=> (
                    <Fragment key={i+''}>
                    {page.results.map((item, j)=> (
                        <ListItem key={i+'.'+j} path={path} item={item}/>
                    ))}
                </Fragment>
                ))}
            </InfiniteScroll>
        </div>
    )}
</div>

Where ListHeader and ListItem are components of your own.

Upvotes: 0

Yashar Habibi
Yashar Habibi

Reputation: 1020

I had this issue. It turns out I was using dataLength in the wrong way. I thought it was supposed to be the total length of items that could be displayed, but instead, it seems it should be the length of items that are currently displayed, so the correct way is should be something like this:

    <InfiniteScroll
      dataLength={page * 10}
      pullDownToRefreshThreshold={50}
      next={loadMoreConversation}
      scrollableTarget="scrollableDiv"
      hasMore={true}
      loader={<h4>Loading...</h4>}
    >
      <ChatItemList
        chatItems={chatItems}
        isInDeleteMode={deleteActive}
        onBottomDrawerHandler={onBottomDrawerHandler}
      />
    </InfiniteScroll>

in this case, I load 10 items per page. I hope this helps you because I searched a lot and did not find an answer until I reached it with all the effort and error.

Upvotes: 72

Related Questions