本页还没有译文
本页 24 段还没译成简体中文,下面显示的是英文原文。React Virtual
还没翻译译自英文(tanstack.com)本页 24 段都还没译
The @tanstack/react-virtual adapter is a wrapper around the core virtual logic.
useVirtualizer
function useVirtualizer<TScrollElement, TItemElement = unknown>(
options: PartialKeys<
ReactVirtualizerOptions<TScrollElement, TItemElement>,
'observeElementRect' | 'observeElementOffset' | 'scrollToFn'
>,
): Virtualizer<TScrollElement, TItemElement>This function returns a standard Virtualizer instance configured to work with an HTML element as the scrollElement.
useWindowVirtualizer
function useWindowVirtualizer<TItemElement = unknown>(
options: PartialKeys<
ReactVirtualizerOptions<Window, TItemElement>,
| 'getScrollElement'
| 'observeElementRect'
| 'observeElementOffset'
| 'scrollToFn'
>,
): Virtualizer<Window, TItemElement>This function returns a window-based Virtualizer instance configured to work with the window as the scrollElement.
React-Specific Options
useFlushSync
type ReactVirtualizerOptions<TScrollElement, TItemElement> =
VirtualizerOptions<TScrollElement, TItemElement> & {
useFlushSync?: boolean
}Both useVirtualizer and useWindowVirtualizer accept a useFlushSync option that controls whether React's flushSync is used for synchronous updates.
- Type:
boolean - Default:
true - Description: When
true, the virtualizer will useflushSyncfromreact-domto ensure synchronous rendering during scroll events. This provides the most accurate scrolling behavior but may impact performance in some scenarios.
When to disable useFlushSync
You may want to set useFlushSync: false in the following scenarios:
- React 19 compatibility: In React 19, you may see the following console warning when scrolling:
Setting
flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task.useFlushSync: falsewill eliminate this warning by allowing React to batch updates naturally. - Performance optimization: If you experience performance issues with rapid scrolling on lower-end devices
- Testing environments: When running tests that don't require synchronous DOM updates
- Non-critical lists: When slight visual delays during scrolling are acceptable for better overall performance
Example
const virtualizer = useVirtualizer({
count: 10000,
getScrollElement: () => parentRef.current,
estimateSize: () => 50,
useFlushSync: false, // Disable synchronous updates
})directDomUpdates
- Type:
boolean - Default:
false - Description: Skip React re-renders for scroll-only updates. When enabled, the virtualizer writes item positions (
top/leftortransform) and the container size (height/width) directly to the DOM, and only re-renders when the visible index range orisScrollingchanges.
Requirements when enabled
- Item elements must be
position: absolute; in'transform'mode they must also be anchored withtop: 0/left: 0. - Item elements must not set the main-axis position in their style — the virtualizer owns
top/leftin'position'mode andtransformin'transform'mode. - The inner size container must receive
virtualizer.containerRefand must not setheight/widthin its style. - For multi-lane layouts (grids / masonry), the cross-axis position (e.g.
left: ${(item.lane * 100) / lanes}%) is stable per item and must still be set in your JSX — only the main axis is automated.
⚠️ This flag is intended to be set once at mount. Toggling it (or
directDomUpdatesMode) at runtime can leave stale inline styles on items and the container.
Note: If you omit
containerRef, the virtualizer makes no direct DOM writes — it writes neither item positions nor the container size. You're then responsible for positioning items and sizing the container yourself (e.g. inonChange), while still benefiting from the skipped re-renders.
Example
const virtualizer = useVirtualizer({
count: 10000,
getScrollElement: () => parentRef.current,
estimateSize: () => 50,
directDomUpdates: true,
})
return (
<div ref={parentRef} style={{ overflow: 'auto', height: 400 }}>
{/* The inner container must use virtualizer.containerRef and not set height */}
<div ref={virtualizer.containerRef} style={{ position: 'relative' }}>
{virtualizer.getVirtualItems().map((item) => (
<div
key={item.key}
ref={virtualizer.measureElement}
data-index={item.index}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
// Do NOT set top/left/transform — the virtualizer handles it
}}
>
Row {item.index}
</div>
))}
</div>
</div>
)directDomUpdatesMode
- Type:
'position' | 'transform' - Default:
'transform' - Description: Controls how
directDomUpdatespositions item elements.'transform'(default): writestransform: translate3d(...). Promotes items to their own compositor layer — usually smoother on long lists, but creates a stacking context and can interfere withposition: fixeddescendants. Item elements must be anchored withposition: absolute,top: 0, andleft: 0.'position': writestop/left. Item elements must beposition: absolute.
Example
const virtualizer = useVirtualizer({
count: 10000,
getScrollElement: () => parentRef.current,
estimateSize: () => 50,
directDomUpdates: true,
directDomUpdatesMode: 'position', // Use top/left instead of transform
})