Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGridPro] feat add last row for infinite scroll rows with intersection observer element #7416

Closed
wants to merge 2 commits into from

Conversation

liho00
Copy link

@liho00 liho00 commented Jan 7, 2023

This feature is adding an empty div with id mui-data-grid-last-row-id this empty div is used for proper infinite scroll purpose, we cant depend on onRowsScrollEnd callback for infinite scroll or cursor-based pagination.

Problem:
For eg. DataGridPro with height 1000px, calling backend infinite scroll with limit 2 items, hence backend returning 2 items and next cursor, the 2 items are rendered on the DataGrid however unable to scroll, as 1 row took 50px only, hence unable handle next cursor infinite scroll.

Screen.Recording.2023-01-07.at.8.23.03.PM.mov

as the video shown, the items loaded from backend but unable to scroll, hence cant fetch again for another cursor items...with the onRowsScrollEnd callback...

Solution:
Infinite scroll should be handle with IntersectionObserver native js api. With the id empty div we can observe the element in viewport and then fetch next cursor items.
Note*: the empty div with id must be always at the last items of the scroll list.

 const handleObserver = useCallback(
    (entries) => {
      if (isFetching) {
        return;
      }
      const [target] = entries;

      if (target.isIntersecting && hasNextPage) {
        fetchNextPage();
      }
    },
    [fetchNextPage, hasNextPage, isFetching]
  );

  useEffect(() => {
    const observer = new IntersectionObserver(handleObserver, { threshold: 0 });

    // https://flaviocopes.com/node-process-nexttick/
    // Calling setTimeout(() => {}, 0) will execute the function at the end of next tick,
    // much later than when using nextTick() which prioritizes the call and executes it just
    // before the beginning of the next tick.
    // the settimeout is prevent observe the last row div before the virtual scroll are rendered.
    setTimeout(() => {
      const element = document.getElementById("mui-data-grid-last-row-id");
      if (element) {
        observer.observe(element);
      }
    });

    return () => {
      const element = document.getElementById("mui-data-grid-last-row-id");
      if (element) {
        observer.unobserve(element);
      }
    };
  }, [fetchNextPage, hasNextPage, handleObserver]);

Result:

Screen.Recording.2023-01-07.at.5.20.38.PM.mp4

I think i have presented the proof of concept and the practical way of implementing the infinite scroll list or cursor based pagination. However i unable to implement it via slot hence I hope maintainer can add it as slot. The slot must always at the last item of the scroll list.

@liho00 liho00 changed the title feat: add last row for intersection observer element [DataGridPro]: feat add last row for intersection observer element Jan 7, 2023
@mui-bot
Copy link

mui-bot commented Jan 7, 2023

These are the results for the performance tests:

Test case Unit Min Max Median Mean σ
Filter 100k rows ms 504 762.6 703.1 653.76 96.093
Sort 100k rows ms 541.2 988 782.7 775.16 150.293
Select 100k rows ms 208.5 287.3 227.7 238.8 29.487
Deselect 100k rows ms 135.7 205.1 188.7 180.8 24.332

Generated by 🚫 dangerJS against 29f9354

@liho00 liho00 changed the title [DataGridPro]: feat add last row for intersection observer element [DataGridPro] feat add last row for intersection observer element Jan 7, 2023
@liho00 liho00 changed the title [DataGridPro] feat add last row for intersection observer element [DataGridPro] feat add last row for infinite scroll rows with intersection observer element Jan 7, 2023
@zannager zannager added the component: data grid This is the name of the generic UI component, not the React module! label Jan 9, 2023
@m4theushw
Copy link
Member

Before reviewing your solution, could you try setting scrollEndThreshold=1? I explained in #4371 (comment) why the problem you described is happening. Can you also create an issue with a minimal reproduction?

@liho00
Copy link
Author

liho00 commented Jan 10, 2023

Before reviewing your solution, could you try setting scrollEndThreshold=1? I explained in #4371 (comment) why the problem you described is happening. Can you also create an issue with a minimal reproduction?

@m4theushw
https://codesandbox.io/s/gifted-einstein-o1xc0e?file=/demo.tsx
Here is the demo of @mui/x-data-grid-pro:v5.17.18

@m4theushw m4theushw added the on hold There is a blocker, we need to wait label Jan 24, 2023
@liho00 liho00 closed this by deleting the head repository Apr 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! on hold There is a blocker, we need to wait
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants