From ba4cff2a44509980c483936933d887b570152487 Mon Sep 17 00:00:00 2001 From: Damian Pieczynski Date: Wed, 7 Jan 2026 21:41:35 +0100 Subject: [PATCH 1/2] revert(virtual-core): "notify framework when count changes" This reverts commit 2542c5a --- docs/api/virtualizer.md | 4 +-- packages/virtual-core/src/index.ts | 5 --- packages/virtual-core/tests/index.test.ts | 38 +++++++++++++++++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/docs/api/virtualizer.md b/docs/api/virtualizer.md index d9110f53..930a2f6b 100644 --- a/docs/api/virtualizer.md +++ b/docs/api/virtualizer.md @@ -136,9 +136,9 @@ The position where the list is scrolled to on render. This is useful if you are getItemKey?: (index: number) => Key ``` -This function is passed the index of each item and should return a unique key for that item. The default functionality of this function is to return the index of the item, but you should override this when possible to return a unique identifier for each item across the entire set. +This function is passed the index of each item and should return a unique key for that item. The default functionality of this function is to return the index of the item, but you should override this when possible to return a unique identifier for each item across the entire set. -**Important:** In React (and similar reactive frameworks), this function **must be memoized** (e.g., using `useCallback`) to prevent infinite re-render loops that will crash your application. Without memoization, the virtualizer will detect the function reference change on every render and trigger measurement recalculation, which causes another render, creating an infinite loop. +**Note:** The virtualizer automatically invalidates its measurement cache when measurement-affecting options change, ensuring `getTotalSize()` and other measurements return fresh values. While the virtualizer intelligently tracks which options actually affect measurements, it's still better to memoize `getItemKey` (e.g., using `useCallback` in React) to avoid unnecessary recalculations. ### `rangeExtractor` diff --git a/packages/virtual-core/src/index.ts b/packages/virtual-core/src/index.ts index fb7bb5e6..6c1cafa4 100644 --- a/packages/virtual-core/src/index.ts +++ b/packages/virtual-core/src/index.ts @@ -645,11 +645,6 @@ export class Virtualizer< }, { key: false, - skipInitialOnChange: true, - onChange: () => { - // Notify when measurement options change as they affect total size - this.notify(this.isScrolling) - }, }, ) diff --git a/packages/virtual-core/tests/index.test.ts b/packages/virtual-core/tests/index.test.ts index 624fb805..6a00c398 100644 --- a/packages/virtual-core/tests/index.test.ts +++ b/packages/virtual-core/tests/index.test.ts @@ -120,3 +120,41 @@ test('should correctly recalculate lane assignments when lane count changes', () }).not.toThrow() }) }) + +test('should update getTotalSize() when count option changes (filtering/search)', () => { + const virtualizer = new Virtualizer({ + count: 100, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + expect(virtualizer.getTotalSize()).toBe(5000) // 100 × 50 + + // Simulate filtering - reduce count to 20 + virtualizer.setOptions({ + count: 20, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + // getTotalSize() should immediately return updated value (not stale) + expect(virtualizer.getTotalSize()).toBe(1000) // 20 × 50 + + // Restore full count + virtualizer.setOptions({ + count: 100, + estimateSize: () => 50, + getScrollElement: () => null, + scrollToFn: vi.fn(), + observeElementRect: vi.fn(), + observeElementOffset: vi.fn(), + }) + + expect(virtualizer.getTotalSize()).toBe(5000) // 100 × 50 +}) From baa7bafd7317b47094f5627904df51bdb41edfa8 Mon Sep 17 00:00:00 2001 From: Damian Pieczynski Date: Wed, 7 Jan 2026 21:48:45 +0100 Subject: [PATCH 2/2] chore: add changeset --- .changeset/hungry-buses-shop.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/hungry-buses-shop.md diff --git a/.changeset/hungry-buses-shop.md b/.changeset/hungry-buses-shop.md new file mode 100644 index 00000000..5ffca860 --- /dev/null +++ b/.changeset/hungry-buses-shop.md @@ -0,0 +1,5 @@ +--- +'@tanstack/virtual-core': patch +--- + +revert(virtual-core): "notify framework when count changes" 2542c5a