T
TanStack11mo ago
other-emerald

Trying to wrap my head around dynamically inserting elements in table

Hello, friends! I apologize for the vagueness in advance; this is my first time using useVirtualizer and I'm still trying to wrap my head around how everything fits together. I'm working on a custom hook that extends useVirtualizer to support a table of expansible/collapsible rows (<tr>). Each <tr> has an onClick handler either passed directly to it or to a child element that causes additional sibling rows to render. I managed to make it work where each "parent" row can have a single child by manually measuring the child and adding that height to the parent. Each parent row is positioned with translateY(virtualItem.start) and children with translateY(virtualItem.end - parentHeights[virtualItem.index]). This works for a single additional row, but would've gotten unwieldy fast as I wanted to support n child rows. For reference, this is the component I'm working on, and this is the virtualized version of the regular table component, without expand/collapse. I tried achieving this using the return value of virtualizer.getVirtualItems() , changing it so it returns an array of [item, []] for closed rows and [item, item[]] for open rows, but this causes rows to jump when the parent row is unmounted; another issue is when sometimes virtualizer.getVirtualItems() returns an empty array. I recognize that all of this is not worth much without a repro case, but I'm hoping more for broad guidance on how to achieve something like (or if it's even possible) this than necessarily fixing a bug. Thanks!
2 Replies
fascinating-indigo
fascinating-indigo11mo ago
Thanks for reaching out! This is a great question, and there are a few different ways to approach it. One key consideration is how many child elements are being hidden or shown at any given time. If the number of expandable rows is relatively small, it might not be worth virtualizing the child rows at all. In that case, managing the layout without virtualization could simplify things.
other-emerald
other-emeraldOP11mo ago
Hey @piecyk! Thank you for helping me with this. I've considered the approach you mention, but hit a wall trying to position each child row "in between" regular rows, especially if the children rows are supposed to be dynamically sized like the parents. This gets further complicated by the fact that there can't be anything between <tbody> and <tr> elements. If I was able to have a container wrapping the parent and children, I could virtualize the parent instead, but alas. I think the main thing I'm struggling with is how to transition between the initial moment where it's a 1:1 match between virtual row <-> parent row, to when a row is expanded and starts consuming multiple virtual rows.

Did you find this page helpful?