user805703
user805703

Reputation: 247

Material-ui DataGrid and Infinite Scroll

I'm currently using material-ui data grid component and find it excellent.

However, for a current feature I'm working on I need to have infinite scroll support within the DataGrid. Has anyone done this previously using material-ui data grid?

Doesn't seem like its supported out of the box reading the docs. I did come across the issue which has some suggestions in the comments.

Keen for any tips on how to use infinite scroll with material-ui data grid

Upvotes: 5

Views: 11540

Answers (3)

fabjiro
fabjiro

Reputation: 1

I have found an acceptable solution (after days of error).

I think the question refers to something similar to the pro version of mui Infinite loading

However I have found a way to do it with the community version.

Version of data grid used: “@mui/x-data-grid”: “^7.22.2”

I have created a custom hook to do the same functionality

// useTableScrollInfinitie.tsx
import { useGridApiRef } from "@mui/x-data-grid";
import { useEffect, useRef } from "react";

interface IProps {
  isLoading: boolean;
  onNextPage: () => void;
  threshold?: number;
}

export const useTableScrollInfinitie = ({ onNextPage, isLoading, threshold = 0 }: IProps) => {
  const gridApiRef = useGridApiRef();
  const scrollMonitor = useRef<Function | null>(null);

  useEffect(() => {
    if (gridApiRef.current?.instanceId) {
      // Obtenemos el elementScroll
      const elementScroll =
        gridApiRef.current.rootElementRef.current?.children[0].children[1];

      // Suscripción al evento scrollPositionChange si no está cargando datos
      if (!isLoading && elementScroll) {
        scrollMonitor.current = gridApiRef.current.subscribeEvent(
          "scrollPositionChange",
          (event) => {
            const maxScrollTop =
              elementScroll.scrollHeight - elementScroll.clientHeight;
            const scrollThreshold = maxScrollTop * (1 - threshold / 100);

            if (event.top >= scrollThreshold) {
              onNextPage();
            }
          }
        );
      }
    }

    // Cleanup al desmontar el componente o cambiar dependencias
    return () => {
      if (scrollMonitor.current) {
        scrollMonitor.current();
      }
    };
  }, [gridApiRef, isLoading]);

  return { gridApiRef };
};

Using it is really simple

 const { gridApiRef } = useTableScrollInfinitie({
    isLoading: isFetching, // api rest fetching
    threshold: 0, // fetch data when scroll to bottom
    onNextPage: () => {
      // fetch more data
    },
  });

and “gridApiRef” we will pass it as props to

  <DataGrid
        apiRef={gridApiRef}
       ...
      />

Here is a little demo

Demo infinite-loading

Upvotes: 0

Ashley Wilson
Ashley Wilson

Reputation: 554

If you set the apiRef prop for DataGrid to a reference returned by useGridApiRef from @mui/x-data-grid, you can subscribe to events generated by the grid through that reference. There's a scrollPositionChange event you can subscribe to, which you can use to manually calculate the position of scroll and use that to determine when to fetch the next page.

There are methods to get the currently loaded number of rows and the scroll position as well.

Relevant code in Typescript below:

const gridApiRef = useGridApiRef();
const scrollMonitor = React.useRef<Function>();

const handleScroll = React.useCallback(() => {
  if (gridApiRef.current?.instanceId) {
    const currentRowCount = gridApiRef.current.getRowsCount();
    const scrollPosition = gridApiRef.current.getScrollPosition();

    // fetch next page when appropriate
  }
}, [gridApiRef.current?.instanceId]);

React.useEffect(() => {
  if (gridApiRef.current?.instanceId) {
    // You can call scrollMonitor.current() to unsubscribe from the event
    scrollMonitor.current = gridApiRef.current.subscribeEvent("scrollPositionChange", (event) => {
      handleScroll();
    }
  });
}, [gridApiRef.current?.instanceId]);

return (<DataGrid apiRef={gridApiRef} ...props />);

Upvotes: 2

Javier Munoz
Javier Munoz

Reputation: 73

Yes, easiest way is to use commercial version. Find it here on infinite Loading section: https://mui.com/x/react-data-grid/row-updates/ Props name is onRowsScrollEnd. This can fire a function to fetch more data.

Upvotes: 4

Related Questions