React Virtual (Legacy)
React Virtual (version 2.10.4) is a JavaScript library providing a single headless hook (`useVirtual`) for efficiently virtualizing scrollable elements in React applications. It enables the rendering of massive lists, grids, and tables by only mounting the visible items in the DOM, drastically improving performance and memory usage for large datasets. This version, last updated over three years ago, was the predecessor to the more actively maintained and feature-rich `@tanstack/react-virtual` (version 3.x.x), part of the broader TanStack ecosystem. While still functional, it is no longer actively developed or recommended for new projects, with development having shifted entirely to the TanStack-branded successor.
Common errors
-
npm WARN Conflicting peer dependency: react@^17.0.2 npm WARN node_modules/react npm WARN peer react@"^16.6.3 || ^17.0.0" from react-virtual@2.10.4
cause `react-virtual` v2.x declares peer dependencies only up to React 17, making it incompatible with React 18+.fixDowngrade your React version to 16 or 17, or preferably, upgrade your virtualization library to `@tanstack/react-virtual` which supports React 18+. -
TypeError: Cannot read properties of null (reading 'scrollTop') or similar errors related to `parentRef.current` being null.
cause The `parentRef` provided to `useVirtual` is not correctly attached to the scrollable DOM element or is accessed before the ref is populated (e.g., during initial render).fixEnsure the `parentRef` is correctly assigned to the `div` element that serves as the scrollable container. Also, ensure that any logic dependent on `parentRef.current` is conditionally executed only after `parentRef.current` is available.
Warnings
- breaking The `react-virtual` package (v2.x) is effectively abandoned. Its successor is `@tanstack/react-virtual` (v3.x), which introduces breaking API changes including renaming `useVirtual` to `useVirtualizer` and modifying hook signatures and behaviors.
- gotcha `react-virtual` v2.10.4 is incompatible with React 18 due to peer dependency conflicts and internal implementations that are not React 18-friendly.
- gotcha Incorrectly providing the `key` prop for virtualized items can lead to performance issues or unexpected UI behavior, especially when item order changes or items are added/removed.
- gotcha The `estimateSize` option is crucial for performance. Providing an inaccurate `estimateSize` can lead to initial jumpiness or incorrect scrollbar behavior, particularly with variable or dynamic item heights.
Install
-
npm install react-virtual -
yarn add react-virtual -
pnpm add react-virtual
Imports
- useVirtual
import useVirtual from 'react-virtual'
import { useVirtual } from 'react-virtual' - useVirtual
const useVirtual = require('react-virtual')const { useVirtual } = require('react-virtual') - VirtualItem
import type { VirtualItem } from 'react-virtual'
Quickstart
import React, { useRef, useCallback, CSSProperties } from 'react';
import { useVirtual } from 'react-virtual';
const RowVirtualizerFixed = () => {
const parentRef = useRef<HTMLDivElement>(null);
const rowCount = 10000;
const rowVirtualizer = useVirtual({
size: rowCount,
parentRef,
estimateSize: useCallback(() => 35, []), // Fixed item height
overscan: 5,
});
return (
<div
ref={parentRef}
style={{
height: `300px`,
width: `100%`,
overflow: `auto`,
}}
>
<div
style={{
height: `${rowVirtualizer.totalSize}px`,
width: `100%`,
position: `relative`,
}}
>
{rowVirtualizer.virtualItems.map(virtualRow => (
<div
key={virtualRow.index}
style={{
position: `absolute`,
top: 0,
left: 0,
width: `100%`,
height: `${virtualRow.size}px`,
transform: `translateY(${virtualRow.start}px)`,
background: virtualRow.index % 2 ? '#eee' : '#fafafa',
display: 'flex',
alignItems: 'center',
paddingLeft: '10px',
borderBottom: '1px solid #ddd',
boxSizing: 'border-box'
}}
>
Row {virtualRow.index}
</div>
))}
</div>
</div>
);
};
export default RowVirtualizerFixed;