From 43c3be1efbc516aac7ead1c196ad93d447f454f2 Mon Sep 17 00:00:00 2001 From: JB Bakst Date: Wed, 29 Oct 2025 16:55:54 -0700 Subject: [PATCH 1/2] fix(virtual-core): scroll to index should only retry if still targeting the same index --- packages/virtual-core/src/index.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/virtual-core/src/index.ts b/packages/virtual-core/src/index.ts index b4794e06..0b923eb0 100644 --- a/packages/virtual-core/src/index.ts +++ b/packages/virtual-core/src/index.ts @@ -366,6 +366,7 @@ export class Virtualizer< scrollOffset: number | null = null scrollDirection: ScrollDirection | null = null private scrollAdjustments = 0 + private scrollToIndexTargetIndex: number | null = null shouldAdjustScrollPositionOnItemSizeChange: | undefined | (( @@ -970,11 +971,17 @@ export class Virtualizer< index = Math.max(0, Math.min(index, this.options.count - 1)) + // If this is called in a tight loop, we don't want our retry logic to trigger for outdated indexes. + // After each async gap, we should check if we're still targeting the same index before trying to scroll. + this.scrollToIndexTargetIndex = index + let attempts = 0 const maxAttempts = 10 const tryScroll = (currentAlign: ScrollAlignment) => { if (!this.targetWindow) return + + if (this.scrollToIndexTargetIndex !== index) return const offsetInfo = this.getOffsetForIndex(index, currentAlign) if (!offsetInfo) { @@ -985,6 +992,8 @@ export class Virtualizer< this._scrollToOffset(offset, { adjustments: undefined, behavior }) this.targetWindow.requestAnimationFrame(() => { + if (this.scrollToIndexTargetIndex !== index) return + const currentOffset = this.getScrollOffset() const afterInfo = this.getOffsetForIndex(index, align) if (!afterInfo) { @@ -1000,6 +1009,8 @@ export class Virtualizer< const scheduleRetry = (align: ScrollAlignment) => { if (!this.targetWindow) return + + if (this.scrollToIndexTargetIndex !== index) attempts++ if (attempts < maxAttempts) { From 0a640987f19d1732d76383b697033fd347535fbc Mon Sep 17 00:00:00 2001 From: JB Bakst Date: Wed, 29 Oct 2025 16:59:41 -0700 Subject: [PATCH 2/2] add changeset --- .changeset/four-places-allow.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/four-places-allow.md diff --git a/.changeset/four-places-allow.md b/.changeset/four-places-allow.md new file mode 100644 index 00000000..b7fdb5c6 --- /dev/null +++ b/.changeset/four-places-allow.md @@ -0,0 +1,5 @@ +--- +'@tanstack/virtual-core': patch +--- + +fix(virtual-core): scroll to index should only retry if still targeting the same index