lit-virtual: VirtualizerController never applies updated options after construction
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 45/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 静か
- 技術スタック
- typescript
- 領域
- frontend
調査の方向性
packages/lit-virtual/src/index.ts から始め、VirtualizerController が構築時にオプションを受け取り、hostUpdated() 中に更新する仕組みを追跡してください。Issue で言及されている react-virtual、angular-virtual、lit-table の adapter パターンを比較し、その後のレンダリングで count などの変更された値が適用される、オプション更新の経路を定義してください。
索引モデルが issue の本文から書いたものです。
説明
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)
- 主要言語
- TypeScript
- スター
- 7.1k
- フォーク
- 472
- 平均マージ
- 1日 14時間
- マージ済み PR(30日)
- 18
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
TanStack/virtual のほかの issue
-
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
TanStack/virtual#1307 · コメント 7 件 ·
メンテナーはふだん 1 日以内に返信
-
anchorTo: 'end' loses the end when the scroll element shrinks対応中かも @langleyd が 5 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
virtual-core: desktop Safari drops the prepend anchor write when history lands during the top rubber-band bounce対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 5/5 1週間以上 初心者へのやさしさ 38/100
メンテナーはふだん 1 日以内に返信
-
marko-virtual: scrollToEnd during an in-flight prepend strands the view one prepend above the bottom (chat-pretext e2e fails on CI)再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープン
難易度 4/5 3〜5日 初心者へのやさしさ 55/100
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 42/100
TanStack/virtual#1252 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
TanStack/virtual の issue をすべて見る
似ている issue
-
./collections should export setUmbracoVersion and setAllowFilePathUploads for in-process consumersオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
umbraco/Umbraco-CMS-MCP-Dev#563 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
-
afk-ok area:data-quality importer size:S
難易度 2/5 1〜3時間 初心者へのやさしさ 77/100
enorm-labs/event-junkie#3166 ·
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 1/5 1時間未満 初心者へのやさしさ 80/100
alunduil/projects-v2-sync#21 ·