Search code examples
javascriptreactjsinfinite-scrollreact-table

React-Table plus InfiniteScroll implementation not updating


I'm trying to implement InfiniteScroll using React-Table, I already have all the data in state, so I'm to implement the InfiniteScroll to show the data a bit at a time since we don't want to use pagination, this is what I have so far

<div
  id="scrollableDiv"
  style={{
    height: 320,
    overflow: 'auto',
    display: 'flex',
  }}
>
  <InfiniteScroll
    dataLength={rows.length}
    next={fetchMoreData}
    hasMore={true}
    style={{ display: 'flex', flexDirection: 'column' }}
    loader={<h4>Loading more items...</h4>}
    scrollableTarget="scrollableDiv"
  >
...
    <tbody {...getTableBodyProps()} className="table-body">
      {rows.slice(0, offset).map((row) => {
        prepareRow(row);
...

My fetchMoreData and offset state are:

const [offset, setOffset] = useState(5);

...

const fetchMoreData = () => {
  setTimeout(() => {
    setOffset(offset + 5);
  }, 100);
};

This works the first time, the table gets 5 more rows, but when you reach the end again nothing happens, the Loading more items message stays and the fetchMoreData function does nothing, what will be the cause for this to work the first time but not after?

Here is a codesandbox with similar code, same concept and problem


Solution

  • According to documentation for next function

    a function which must be called after reaching the bottom. It must trigger some sort of action which fetches the next data. The data is passed as children to the InfiniteScroll component and the data should contain previous items too. e.g. Initial data = [1, 2, 3] and then next load of data should be [1, 2, 3, 4, 5, 6].

    so your fetchMoreData function

      fetchMoreData = () => {
        if (this.state.items.length >= 500) {
          this.setState({ hasMore: false });
          return;
        }
        // a fake async api call like which sends
        // 20 more records in .5 secs
        setTimeout(() => {
          this.setState({
            offset: this.state.offset + 5
          });
        }, 500);
      };
    

    doesnt increase somehow the original array of items but rather it sets the offset, that's why it keeps saying "Loading". If you push some new items inside your this.state.items array, it will work.