Virtualized list wrapper keeps stale height after data changes
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.1k
- Forks
- 466
- Avg merge
- 2d 31m
- Merged PRs (30d)
- 13
Description
Describe the bug
Summary
List uses useWindowVirtualizer for row virtualization, but the outer div’s inline
height is read directly from rowVirtualizer.getTotalSize() during render. Because the
virtualizer instance is stable and the getter mutates internal state without changing referential
identity, React never receives a new height value when the rows array is filtered or otherwise
resized. The wrapper therefore preserves an outdated, overly tall height, leaving a large blank
spacer below the visible rows and causing scroll position jumps.
Impact
Any operation that changes the number of rows (search, filters, pagination reset) leaves the
list container at its previous height. Users see excessive empty space and the scroll bar no
longer reflects the actual result size.
Root Cause
getTotalSize() is invoked inline inside JSX. The virtualizer recomputes its measurement cache,
but React doesn’t detect that the returned string (e.g., "32000px") should change because the
component never re-renders with a different computed value tied to the rows count.
Fix in my case
Memoize the total height using useMemo(() => rowVirtualizer.getTotalSize(), [rowVirtualizer, rows.length]) and pass that memoized number to the style prop. This forces a fresh height
string whenever the virtualizer’s count changes, keeping the spacer in sync. Implemented in commit
Your minimal, reproducible example
https://github.com/kosovatools/kosovatools.org/commit/da4a20196356fd7d96e0fb9b69be9bd662294eeb
Steps to reproduce
.
Expected behavior
Height react to count change
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
Firefox
tanstack-virtual version
3.13.12
TypeScript version
5.7.3
Additional context
No response
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the List component that uses useWindowVirtualizer and inspect how rows.length and getTotalSize() feed the wrapper style. Compare the behavior with commit da4a20196356fd7d96e0fb9b69be9bd662294eeb and reproduce a filter or pagination change. Done means the wrapper height and scrollbar reflect the updated row count without excess blank space.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend, performance
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100