You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Virtualized list wrapper keeps stale height after data changes #1077
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
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.
changed the title [-]Virtualized victim list wrapper keeps stale height after data changes[/-][+]Virtualized list wrapper keeps stale height after data changes[/+]on Nov 8, 2025
Thanks for the report! It looks like your app has reactCompiler: true in apps/web/next.config.ts. The compiler memoizes rowVirtualizer.getTotalSize() against the stable rowVirtualizer instance, so the value isn't recomputed when count changes. Without the compiler, calling getTotalSize() during render always reflects the current count (covered by a virtual-core test since #1112). Note that #1085 was reverted in #1112 because it caused infinite re-renders (#1092).
Workaround: opt the component out of the compiler by adding the "use no memo" directive at the top of VictimList (the component that calls useWindowVirtualizer):
exportfunctionVictimList(props){"use no memo";constrowVirtualizer=useWindowVirtualizer({/* ... */});// ...}
Your explicit useMemo keyed on victims.length also works, but "use no memo" keeps the rest of the virtualizer output (getVirtualItems(), etc.) fresh too.
Closing as a duplicate of #736; the React Compiler incompatibility is tracked in #1119. If "use no memo" doesn't fix it for you, let us know and we'll reopen.
Activity
[-]Virtualized victim list wrapper keeps stale height after data changes[/-][+]Virtualized list wrapper keeps stale height after data changes[/+]shunn2 commentedon Dec 16, 2025
Hi @kosovatoolsadmin Maybe #1085 I think this PR will solve the issue you raised
KillerCodeMonkey commentedon Apr 13, 2026
no need for that, just check if you have memorized your
getItemKeyfunction.Maybe there are some deps missing when the key should be recalculated.
piecyk commentedon Oct 10, 2026
Thanks for the report! It looks like your app has
reactCompiler: trueinapps/web/next.config.ts. The compiler memoizesrowVirtualizer.getTotalSize()against the stablerowVirtualizerinstance, so the value isn't recomputed whencountchanges. Without the compiler, callinggetTotalSize()during render always reflects the currentcount(covered by a virtual-core test since #1112). Note that #1085 was reverted in #1112 because it caused infinite re-renders (#1092).Workaround: opt the component out of the compiler by adding the
"use no memo"directive at the top ofVictimList(the component that callsuseWindowVirtualizer):Your explicit
useMemokeyed onvictims.lengthalso works, but"use no memo"keeps the rest of the virtualizer output (getVirtualItems(), etc.) fresh too.Closing as a duplicate of #736; the React Compiler incompatibility is tracked in #1119. If
"use no memo"doesn't fix it for you, let us know and we'll reopen.