SolidJS: warning "Missing attribute name 'data-index={index}' on measured element."
Describe the bug
Looks like virtualizer.measureElement is not working with SolidJS
<For each={virtualizer.getVirtualItems()}>{(item) =>
<div
class={item.index % 2 ? 'ListItemOdd' : 'ListItemEven'}
data-index={item.index}
ref={virtualizer.measureElement}
style={{
border: "1px solid red",
"box-sizing": "border-box",
"height": "150px"
}}
>
Row {item.index}
</div>
}</For>
Dirty workaround:
<For each={virtualizer.getVirtualItems()}>{(item) =>
<div
class={item.index % 2 ? 'ListItemOdd' : 'ListItemEven'}
data-index={item.index}
ref={(el) => {
el.dataset.index = item.index.toString(); // <--- see this!
virtualizer.measureElement(el);
}}
style={{
border: "1px solid red",
"box-sizing": "border-box",
"height": "150px"
}}
>
Row {item.index} {Date.now()}
</div>
}</For>
Your minimal, reproducible example
https://codesandbox.io/p/devbox/9rkhxf
Steps to reproduce
Just add
data-index={item.index}
ref={virtualizer.measureElement}
Expected behavior
No warning
How often does this bug happen?
None
Screenshots or Videos
No response
Platform
Chromium 133.0.6943.98
tanstack-virtual version
3.13.0
TypeScript version
No response
Additional context
No response
Terms & Code of Conduct
- [x] I agree to follow this project's Code of Conduct
- [x] 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.
i seem to be able to work around this particular issue by setting the data-index attribute in the ref callback:
ref={(el) => {
el.dataset.index = `${row.index}`;
virtualizer.measureElement(el);
}}
still having other problems like the measured height only affecting the total size when scrolling... and only getting that far when wrapping the createVirtualizer call in a createMemo (because my count changes with every infiniteQuery.fetchNextPage), which i don't even know i'm supposed to do or not (edit: okay, i'm pretty sure i shouldn't do that as it'll re-initialize the virtualizer on every data change, which i don't want. an effect that sets virtualizer.options.count to the updated count seems to work, though). i'd love to see a working, best practice example tbh
quick update: in this example, they're doing this:
ref={(el) => queueMicrotask(() => virtualizer.measureElement(el))}
i don't know if that's the way to go or not, but it seems to work far better than my hack
The data-index={index} is same as createRenderEffect(() => el.dataset["index"] = index), which is run after the ref callback, so the attribute is not exists at the moment. You can use onMount (or createEffect) to schedule the task behind the render effect.
Now I use virtua