Skip to content

Conversation

@siriwatknp
Copy link
Member

@siriwatknp siriwatknp commented Sep 25, 2025

closes #16674
closes #18878

Preview: https://deploy-preview-19700--material-ui-x.netlify.app/x/react-data-grid/server-side-data/recipes/#cursor-based-pagination

Summary

This PR enhances the Data Grid documentation by adding comprehensive examples and explanations for cursor-based pagination, addressing a common server-side data pattern where traditional offset pagination isn't suitable.

Changes

Documentation Updates

  • docs/data/data-grid/server-side-data/recipes.md
    • Added new "Cursor-based pagination" section explaining the concept and requirements
    • Documented two implementation approaches: blocking and non-blocking
    • Included clear explanations of when to use each approach

New Demo Components

  1. ServerSideCursorBlocking.js - Blocking approach

    • Controls paginationModel state to ensure cursor availability
    • Simpler implementation, suitable for most use cases
    • Prevents navigation until previous response arrives
  2. ServerSideCursorNonBlocking.js - Non-blocking approach

    • Uses custom cache with pushKey() and getLast() methods
    • Allows immediate pagination with request queuing
    • More complex but provides better UX for fast navigation

Technical Implementation

Blocking Approach

  • Updates pagination model only when cursor is available
  • Uses mapPageToNextCursor ref to track cursors
  • Conditional pagination model updates based on cursor availability

Non-blocking Approach

  • Custom Cache class implementation
  • Request order tracking before responses arrive
  • Asynchronous cursor resolution for seamless navigation

Benefits

  • Clear guidance: Developers now have concrete examples for implementing cursor pagination
  • Multiple strategies: Covers different UX requirements and complexity levels
  • Production-ready: Examples include proper state management and edge case handling
  • Educational: Demonstrates advanced Data Grid features like paginationMeta and custom caching

@siriwatknp siriwatknp added scope: data grid Changes related to the data grid. type: new feature Expand the scope of the product to solve a new problem. labels Sep 25, 2025
@mui-bot
Copy link

mui-bot commented Sep 25, 2025

Deploy preview: https://deploy-preview-19700--material-ui-x.netlify.app/

Updated pages:

Bundle size report

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-premium 0B(0.00%) 0B(0.00%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)

Details of bundle changes

Generated by 🚫 dangerJS against 64d79ee

@siriwatknp siriwatknp changed the title [Data Grid] Support cursor pagination with recipe [Data Grid] Add recipe for cursor pagination with data source Sep 30, 2025
@siriwatknp siriwatknp requested a review from a team September 30, 2025 04:27
@siriwatknp siriwatknp marked this pull request as ready for review September 30, 2025 04:27
Copy link
Member

@michelengelen michelengelen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but I'll defer the approval to @MBilalShafi who has more insight into this feature

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we block the switching of the next page in this demo like the one in unknown case here until the page being fetched has been fetched to avoid incorrect values set for all the skipped pages?

Screen.Recording.2025-10-20.at.23.44.49.mov

Copy link
Member

@MBilalShafi MBilalShafi Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the methods getLast and pushKey are used in the userland and not used internally, for a better separation of concerns, does it makes sense to use the default data source cache (not pass a custom one) and maintain a separate class encapsulating cacheKeys, getLast, and pushKey in the userland and consume it in the dataSource.getRows() method?

If needed, it can interact with the internal cache using apiRef.current.dataSource.cache.

Wdyt?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so.

  1. apiRef.current.dataSource.cache is not documented yet
  2. it sounds more complicated than let user handle their own cache (there could be project specific logic that we haven't think of), so for simplicity, let's use a custom cache implementation which is already documented.

columns={columns}
dataSource={dataSource}
dataSourceCache={cache}
pagination
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add an error handling (onDataSourceError()) to this demo, causing the page to reset on the last loaded one if one of them fails?

Because all the responses are chained together, if one of them fails, the view will remain into loading state forever.

Example: https://stackblitz.com/edit/gy5p4ufa?file=src%2FDemo.tsx

Screen.Recording.2025-10-21.at.00.03.43.mov

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. I think if there is an error, the page will have to reset back to the latest success query

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is updated version with error handling. I set the error to happen on page 8 to demonstrate the error handling. I took this approach because it's the simplest one.

I tried to use onDataSourceError but it does not work well for this non-blocking demo.

Screen.Recording.2568-10-21.at.16.52.03.mov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: data grid Changes related to the data grid. type: new feature Expand the scope of the product to solve a new problem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[data grid] Clarification for dataSource usage and cursor-based pagination [data grid] Add cursor based pagination demo for the data source

4 participants