Repository navigation
Replies: 1 comment
|
+1, and it pairs naturally with #6658: exclude-mode selection over rows that were never loaded only makes sense if the table also accepts that rows can be missing. Some things the design probably needs to pin down:
Until something like this lands, you can get the same UX in userland by virtualizing over const BLOCK = 50
const virtualizer = useVirtualizer({
count: rowCount, // full server count, not data.length
getScrollElement: () => scrollRef.current,
estimateSize: () => 36,
overscan: 10,
})
const items = virtualizer.getVirtualItems()
const firstBlock = Math.floor((items[0]?.index ?? 0) / BLOCK)
const lastBlock = Math.floor((items.at(-1)?.index ?? 0) / BLOCK)
const blocks = useQueries({
queries: Array.from({ length: lastBlock - firstBlock + 1 }, (_, i) => {
const block = firstBlock + i
return {
queryKey: ['rows', sorting, filters, block],
queryFn: ({ signal }) =>
fetchRows({ offset: block * BLOCK, limit: BLOCK, sorting, filters, signal }),
staleTime: 60_000,
}
}),
})
// index -> loaded row (or undefined = render a skeleton row)
const rowAt = (index: number) =>
blocks[Math.floor(index / BLOCK) - firstBlock]?.data?.[index % BLOCK]Pass only the loaded rows as The limit of the userland version is exactly what this proposal fixes: the table itself doesn't know the real index of a row, so keyboard navigation, |
Uh oh!
There was an error while loading. Please reload this page.
We have a remote table. The server has 100,000 rows, and we load 50 rows at a time. The server also tells us the total row count. We set
countto it. Now the scrollbar has the correct length, and the user can drag it to the end.But then the app loads page after page. The loading animation continues until the app has loaded all rows up to the scroll position. To show row 99,999, the app must load 2,000 pages, one after the other. If each page takes 300 ms, the user waits 10 minutes. The server also sends 99,950 rows that the user does not want to see.
The cause is that
datacannot have gaps:getRowModel().rows[i]is then not rowion the server.getRowIdgets no data for a row that is not loaded.Idea: an opt-in feature that uses
rowCountas the total. The table shows a placeholder row for each row that is not loaded. The table does not load data. It tells the app which ranges are missing, and the app loads them, for example with TanStack Query. For a jump to row 99,999, the app loads only the visible rows, not 2,000 pages.A placeholder row has a temporary ID. The table keeps no selection, pinning, or expanding state for it.
The feature needs two things from the server: the total row count and rows by offset. Without them, the current infinite scrolling pattern stays the correct choice.
Related: #2385
All reactions