Founding price: $35, then $99 after 23:59 UTC on 4 November, then $99
Get ProRender only the rows in view of a very long list, with a scroll element ref, dynamic row measuring and scroll to index, built on TanStack Virtual.
Derived from this item’s props table, because it declares no controls of its own. This item has no standalone playground, so changes update the code, the share link and the AI prompt.
Use it for lists, logs, tables and menus with thousands of rows, where rendering every row would slow the page.
Do not use it for lists of a few dozen rows; plain rendering is simpler and keeps native find in page and accessibility trees whole.
This hook uses @tanstack/react-virtual; the CLI installs it for you.
import { useVirtualList } from "@/hooks/use-virtual-list"const { parentRef, items, totalSize, scrollToIndex } = useVirtualList({ count: rows.length, estimateSize: 40 })
<div ref={parentRef} className="h-80 overflow-auto">
<div style={{ height: totalSize, position: "relative" }}>
{items.map((row) => (
<div key={row.key} style={{ position: "absolute", insetBlockStart: 0, insetInline: 0, transform: `translateY(${row.start}px)`, height: row.size }}>
{rows[row.index].name}
</div>
))}
</div>
</div>useVirtualList(options): { parentRef, items, totalSize, scrollToIndex, measureElement }
| Option | Type | Default | Description |
|---|---|---|---|
count | number | - | Number of rows. |
estimateSize | number | (index) => number | - | Row height in px (or width when horizontal). |
overscan | number | 5 | Extra rows rendered outside the view. |
horizontal | boolean | false | Virtualise columns instead of rows. |
initialSize | number | - | Scroll element height in px before it is measured; useful for server rendering and tests. |
items is the list of { index, key, start, size } to render. Put ref={measureElement} and data-index={index} on a row to measure its real height. scrollToIndex(index, options?) scrolls a row into view.
Virtualised lists remove rows from the page, so assistive technology cannot reach them with browse mode. Use role="list" or role="grid" with aria-rowcount, aria-setsize and aria-posinset on each rendered row, and keep keyboard navigation working with scrollToIndex.
The hook ships with renderHook tests (use-virtual-list.test.ts) covering its behaviour, cleanup on unmount and server-safe defaults. It is safe to render on the server.