ant-design: Infinite scroll for Ant Table

What problem does this feature solve?

As great as ant’s pagination is, it is also something that is not very modern. I’d like to wrap the table in a infinite scroll that would make ajax request and fetch more rows upon scrolling (Refer here). This is a simple example of creating such a table.

What does the proposed API look like?

To be honest, am not too sure at this point.

For a start we could wrap the Table in an InfiniteLoader HOC and have a event handler prop on the table onScroll that is triggered when the table is scrolled. The purpose of the InfiniteLoader would be to help break large data sets down into chunks that could be just-in-time loaded as they were scrolled into view.

I’ll be happy to send forth a PR if you think this might be useful. If not, please feel free to close this item.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 18
  • Comments: 18 (5 by maintainers)

Most upvoted comments

Wohoo, it is very easy to implement dynamic rows loading/infinite scrolling on antd table, I can chunk the httpRequest with this code:

componentDidMount() {
...
var tableContent = document.querySelector('.ant-table-body')
    tableContent.addEventListener('scroll', (event) => {
      // checking whether a selector is well defined
      console.log('yes, I am listening')
      let maxScroll = event.target.scrollHeight - event.target.clientHeight
      let currentScroll = event.target.scrollTop
      if (currentScroll === maxScroll) {
         // load more data
      }
    })
...
}

I don’t think this feature should be included in antd. For it’s hard to decide that which element’s scroll events we should listen to.

And you can implement this in your own component easily.

I would like this feature too or at least the capability to render more data dynamically.

@burubur Nice implementation. But it’s actually a bad practice to get element with a css selector that’s not in your control.

@benjycui

I don’t think this feature should be included in antd.

It’s rational for a Table/List component to have a onscroll interface.

For it’s hard to decide that which element’s scroll events we should listen to.

I don’t understand.

And you can implement this in your own component easily.

And don’t just kick a feature request back to your user just because it’s easy to implement.

@burhanmubarok thank you for a nice example, I’m starting to use this, but there are problems in some cases.

For example, if my window height is 1000px, and I want to load 10 items per page/scroll, and height of each item is 50px, your example will not be working. Because scrollbar of tbody will not be rendered, I will be not able to scroll more.

@afc163 this feature is very important, I think you need to implement it. I’m starting my third project with ant.design and have the same issue with this.

@burhanmubarok , thanks for the snippet. Better to use refs to access the element and add the scroll listener though! 😸

With @burubur’s suggestion it does work but there are a couple user experience errors:

  • The antd table automatically scrolls to top when I load new data so it makes the user jump all over the page
  • It also still displays incorrect pagination numbers at the bottom (why should there be pages if we have infinite scroll?)
  • The the scroll is on the table instead of being on the page (minor) - this is also causing my columns to be misaligned but no biggy

It would be great if the antd team would listen to this feature request.

This infinite load is required and Pagination is not possible when data source is something like Firebase Firestore where the total number of documents is not known. In such case, either there should be this functionality of Infinite scroll-to-load or at least a “Load More” at the bottom like the Ant List. In current one, I’ve to implement a “Load more” feature.

@afbarbaro

You can’t, for now. There’s no mechanism, as of yet, in antd to attach a ref to the Table component. It’s hacky, but here’s what I did…

Query for the element and attach the scroll event listener

useEffect(() => {
  const node = document.querySelector<HTMLElement>(".table .ant-table-body");
  if (node) {
    node.addEventListener("scroll", () => {
      const perc = (node.scrollTop / (node.scrollHeight - node.clientHeight)) * 100;
      if (perc >= 100) {
        console.log("TODO: Scrolling has reached bottom, load more data, or do whatever...");
      }
    });
  }
});

Tell the table to NOT automatically reset the scroll position on dataSource change

<Table
  className="table"
  scroll={{ scrollToFirstRowOnChange: false }}
  ...
/>

A few things to note:

  • Querying the DOM by the .ant-table-body CSS class isn’t a good idea. At the very least, wrap the table with a unique className so that it’s at least isolated. It’s just a stop-gap approach until a proper way to attach a ref is implemented in antd.

  • The way perc is calculated may need adjustment based on the use-case. More specifically, using either clientHeight vs. offsetHeight.

  • I didn’t run into any issues with the scroll event listener being added more than once, but that doesn’t mean that’s the case every time. Test thoroughly to be sure.