lit-virtual: VirtualizerController never applies updated options after construction
Maintainer antworten meist innerhalb von 1 Tag
@itisrmk arbeitet bereits daran.
Seit 20.10.2026.
Bewertung
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Anfängerfreundlichkeit
- 45/100
- Issue-Typ
- Bug
- Klarheit
- Größtenteils klar
- Aktivitätsstatus
- Ruhig
- Tech-Stack
- typescript
- Bereich
- frontend
Rechercherichtung
Beginne mit packages/lit-virtual/src/index.ts und verfolge, wie VirtualizerController während der Konstruktion Optionen erhält und während hostUpdated() aktualisiert wird. Vergleiche die im Issue erwähnten Adaptermuster von react-virtual, angular-virtual und lit-table und definiere anschließend einen Pfad zur Aktualisierung von Optionen, dessen vollständiges Verhalten geänderte Werte wie count bei nachfolgenden Renderings anwendet.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Describe the bug
VirtualizerController (packages/lit-virtual/src/index.ts) never calls setOptions() after the initial construction, so reactive option updates (a changed count, estimateSize, getScrollElement, etc.) never reach the underlying Virtualizer instance.
constructor(
host: ReactiveControllerHost,
options: VirtualizerOptions<TScrollElement, TItemElement>,
) {
...
this.virtualizer = new Virtualizer(resolvedOptions) // options captured once, here
;(this.host = host).addController(this)
}
hostUpdated() {
this.virtualizer._willUpdate() // no setOptions() call
}
Every other adapter calls setOptions() on every render/update before _willUpdate(). For comparison, react-virtual's useVirtualizer:
instance.setOptions(resolvedOptions)
...
return instance._willUpdate()
and angular-virtual:
virtualizer.setOptions(resolvedOptions())
...
reactiveVirtualizer()._willUpdate()
lit-table's equivalent TableController (same Lit ReactiveController shape, different package) does call the table-core equivalent of setOptions on every access, so this isn't a Lit-specific limitation, lit-virtual just doesn't do it.
Since VirtualizerController is meant to be instantiated once in the host's constructor (the documented usage pattern, same as any other Lit ReactiveController), there's no way for a consumer to get a changed count or other option applied short of reaching into getVirtualizer() and calling .setOptions() manually, which isn't documented anywhere and defeats the point of passing options to the constructor in the first place.
Your minimal, reproducible example
import { LitElement, html } from 'lit'
import { VirtualizerController } from '@tanstack/lit-virtual'
class MyList extends LitElement {
count = 10
virtualizerController = new VirtualizerController(this, {
count: this.count,
estimateSize: () => 35,
getScrollElement: () => this.renderRoot.querySelector('#scroller'),
})
grow() {
this.count = 1000
this.requestUpdate()
}
render() {
const virtualizer = this.virtualizerController.getVirtualizer()
// virtualizer.options.count is still 10 after grow(), even though
// this.count is 1000 and the component re-rendered
return html`<div id="scroller">${virtualizer.getVirtualItems().length} items</div>`
}
}
Steps to reproduce
- Create a
VirtualizerControllerwith an initialcount. - Change the value backing
countand callrequestUpdate()on the host. - Read
virtualizer.options.count(or observe the rendered item count), it still reflects the value from construction time.
Expected behavior
Option changes on subsequent renders should reach the virtualizer, the same as every other framework adapter.
Worth noting this needs more than adding a setOptions() call inside hostUpdated(): the constructor is the only place options is ever received (options: VirtualizerOptions<...>, not a getter), so even a hostUpdated() call would just re-apply the same closed-over object from construction time. The API shape itself doesn't have a channel for fresh options to flow in after construction. lit-table's TableController sidesteps this by exposing a .table(tableOptions, selector) method that's called fresh from render() on every pass rather than once from the constructor, that shape (or an equivalent public setOptions() method consumers call from render()) looks like the fix, not just wiring hostUpdated() to an already-stale value.
Platform
n/a, framework-adapter logic (packages/lit-virtual/src/index.ts)
- Vorherrschende Sprache
- TypeScript
- Sterne
- 7.2k
- Forks
- 479
- Ø Merge
- 21 Std. 1 Min.
- Gemergte PRs (30 T.)
- 41
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Hat eine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus TanStack/virtual
-
anchorTo: 'end' loses the end when the scroll element shrinksEvtl. vergeben @langleyd hat das vor 22 Tagen übernommen. Offen
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 68/100
Maintainer antworten meist innerhalb von 1 Tag
-
marko-virtual: scrollToEnd during an in-flight prepend strands the view one prepend above the bottom (chat-pretext e2e fails on CI)Evtl. vergeben @prayaggaikwad96 hat das vor 16 Tagen übernommen. Offen
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 55/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 42/100
TanStack/virtual#1252 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
eslint-plugin-react-hooks v7 warning for useVirtualizer: Compilation Skipped: Use of incompatible libraryEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. Offen
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 45/100
TanStack/virtual#1119 · 11 Kommentare · 32 Reaktionen ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 35/100
TanStack/virtual#1099 · 1 Reaktion ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in TanStack/virtual
Ähnliche Issues
-
Shell: serve the home app's Cookie Policy on a hard reloadEvtl. vergeben @2001anshkaushik hat das heute übernommen. Offenfeature module:ai
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 88/100
rocketride-org/rocketride-server#2899 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 2 Tagen
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
wazuh/wazuh-dashboard-plugins#9551 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
gofish-graphics/gofish-graphics#1252 ·
Maintainer antworten meist innerhalb von 1 Tag
-
optimization P3 size:XS
Schwierigkeit 1/5 1-3 Stunden Anfängerfreundlichkeit 88/100
josephfung/curia#2366 ·
Maintainer antworten meist innerhalb von 1 Tag
-
type:bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 65/100
nightgauge/nightgauge#2688 ·
Maintainer antworten meist innerhalb von 1 Tag