Apestein / better-react-infinite-scroll

Better react infinite scroll component using intersection observer API.
https://www.npmjs.com/package/better-react-infinite-scroll
17 stars 3 forks source link

[Feature] add a AsyncInfiniteScroll component #15

Open tohsaka888 opened 3 days ago

tohsaka888 commented 3 days ago

Hi, @Apestein,

better-react-infinite-scroll is a great library that helps in building infinite scrolling components. However, it has some limitations, such as rendering a large number of DOM nodes (e.g., 10,000 items) which can lead to performance issues and even cause the browser to crash.

To address this, I propose building an asynchronous infinite scrolling component that only renders a specified threshold of data (e.g., 100 items). This component will fetch the next page of data from the server when the user scrolls to the top or bottom, thereby achieving true infinite scrolling. Below is my vision for the component:

interface AsyncInfiniteScrollProps<T>
  extends React.HTMLAttributes<HTMLDivElement> {
  /**
   * Function to fetch the next page of data.
   * @param lastItem - The last item in the current list.
   * @returns A promise that resolves to an array of items.
   */
  fetchNextPage: (lastItem: T) => Promise<T[]>;

  /**
   * Function to fetch the previous page of data.
   * @param firstItem - The first item in the current list.
   * @returns A promise that resolves to an array of items.
   */
  fetchPreviousPage: (firstItem: T) => Promise<T[]>;

  /**
   * Message to display while loading.
   * @type React.ReactNode
   */
  loadingMessage: React.ReactNode;

  /**
   * Message to display at the end of the list.
   * @type React.ReactNode
   */
  endingMessage: React.ReactNode;

  /**
   * Initial data to display.
   * @type T[]
   */
  initialData: T[];

  /**
   * Number of items to keep in the rendered list.
   * @type number
   * @default 100
   */
  threshold?: number;

  /**
   * Function to render each item.
   * @param item - The item to render.
   * @returns A React node.
   */
  renderItem: (item: T) => React.ReactNode;

  /**
   * Function to generate a unique key for each item.
   * @param item - The item to generate a key for.
   * @returns A unique string key.
   */
  renderKey: (item: T) => string;
}
tohsaka888 commented 3 days ago

Here is a Demo