-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Description
TanStack Table version
8.21.3
Framework/Library version
React 18.3.1 and later
Describe the bug and the steps to reproduce it
When using TanStack Table together with TanStack Virtual for virtualized rows, the table behaves incorrectly when it’s placed inside tabbed content where inactive tabs are hidden via display: none.
The issue can be reproduced starting from the official Virtualized Rows Example.
I modified the example as follows:
Added two tabs:
Tab 1: contains the virtualized table
Tab 2: contains a simple list of columns (content irrelevant)
Inactive tabs are hidden using:
style={{ display: tab === 'tab1' ? 'block' : 'none' }}
Added console logs for debugging.
Case 1: Large dataset (ROW_COUNT = 50_000, note that 2,000 is also enough)
Table is loaded in the first tab.
Click the second tab. After few seconds you get this error:
Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
The error originates from repeated onChange calls inside useVirtualizerBase():
function useVirtualizerBase(...) {
onChange: (instance, sync) => {
...
rerender(); // last function called from index.tsx
}
}
Console output shows TableBodyRow being rendered excessively:
=== virtualRow.start=0 virtualRow.index=775 index=0 scrollTop=0
...
=== virtualRow.start=957 virtualRow.index=1558 index=783 scrollTop=0
Case 2: Small dataset (ROW_COUNT = 40)
- Scroll to the bottom of the table (last row visible)
- Switch to the second tab
- Switch back to the first tab
Observed behavior
Firefox: Table becomes nearly empty (few or no rows visible)
Chrome: Table resets scroll position to the top
Analysis
The virtualizer continues performing layout and scroll calculations while its container is hidden (display: none), which leads to:
Excessive state updates and re-renders
Incorrect scroll state when the tab becomes visible again
Proposed Solution
Skip all virtualizer calculations and updates when the container is hidden, e.g. by checking
tableContainerRef.current?.getClientRects().length === 0
Additional Notes
This issue affects any setup where the table container may be temporarily hidden (e.g., modals, accordions, collapsible panels), not just tabs.
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
https://codesandbox.io/p/devbox/eloquent-rumple-q4lgdn?file=%2Fsrc%2Fmain.tsx%3A330%2C1
Screenshots or Videos (Optional)
Do you intend to try to help solve this bug with your own PR?
None
Terms & Code of Conduct
- I agree to follow this project's Code of Conduct
- I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.