React Virtual List
rc-virtual-list is a React component designed for efficiently rendering large lists by only rendering items visible within the viewport, significantly improving performance and memory usage compared to rendering all items simultaneously. It supports animations and is compatible with older browsers like IE11+. The package, currently at stable version `3.19.2`, receives regular patch updates, indicating an active maintenance schedule. It is part of the `react-component` ecosystem, known for providing foundational UI components often utilized within Ant Design. Its key differentiators include built-in animation support, broad browser compatibility, and a focus on core virtualization logic without opinionated styling, making it highly adaptable to various design systems. It enables smooth scrolling and interaction even with thousands of data entries by precisely managing what's rendered to the DOM.
Common errors
-
Each child in a list should have a unique 'key' prop.
cause `itemKey` prop is either missing or set to an unstable value (like array index) when the list items change.fixSet the `itemKey` prop to a stable, unique identifier for each item in your `data`. For example, `<List data={items} itemKey="id">`. -
TypeError: Cannot read properties of undefined (reading 'scrollTo')
cause Attempting to call an instance method (e.g., `scrollTo`) on the `List` component before it's mounted or if the ref is not properly attached/has not resolved.fixEnsure you are using `React.useRef` (or `createRef` for class components) and accessing the method only after the component has rendered and the ref's `current` property is not null. Example: `listRef.current?.scrollTo(offset);` -
Items disappear or reappear incorrectly on scroll, or list jumps unexpectedly.
cause Often related to incorrect `itemHeight` for items with varying heights, incorrect `itemKey` usage, or aggressive memoization preventing re-render when `data` changes.fixVerify `itemKey` is unique and stable. If item heights vary, ensure `itemHeight` is an accurate average or estimated height for proper scroll calculations. Check if the `data` prop is changing as expected and not being incorrectly memoized, preventing the list from updating.
Warnings
- breaking The `rc-virtual-list` repository now also publishes `@rc-component/virtual-list` starting from `1.x.x` versions. While `rc-virtual-list` `3.x.x` is still actively maintained, `@rc-component/virtual-list` may represent a future major iteration or a complete renaming of the package. Directly migrating between `rc-virtual-list` and `@rc-component/virtual-list` is likely a breaking change due to potential API differences and import path changes.
- gotcha The `itemKey` prop is critical for correct and performant rendering in virtualized lists. Using an unstable value (like array `index`) for `itemKey` when the `data` array can change order, or items can be added/removed from the middle, will lead to rendering glitches, incorrect element state, and potential performance issues.
- gotcha If the height of items changes dynamically after initial render, and the `itemHeight` prop is a fixed number, the virtual list may miscalculate scroll positions, leading to unexpected jumps or blank spaces.
- deprecated As of `v3.18.4`, internal reliance on `ReactDOM.findDOMNode` has been removed. While this is primarily an internal improvement aligning with modern React practices, projects that might have inadvertently relied on `findDOMNode` being used somewhere within the `rc-virtual-list` component tree (e.g., for specific DOM manipulation hacks) might experience subtle behavioral shifts.
Install
-
npm install rc-virtual-list -
yarn add rc-virtual-list -
pnpm add rc-virtual-list
Imports
- List
import { List } from 'rc-virtual-list'; // Incorrect as 'List' is a default export const List = require('rc-virtual-list').List; // Incorrect for default export in CJSimport List from 'rc-virtual-list';
- ListProps
import type { ListProps } from 'rc-virtual-list'; - CommonJS require
const List = require('rc-virtual-list'); // May work in some bundlers, but '.default' is safer for default exportsconst List = require('rc-virtual-list').default;
Quickstart
import React, { useState, useEffect } from 'react';
import List from 'rc-virtual-list';
interface Item {
id: number;
value: string;
}
const VirtualizedListExample: React.FC = () => {
const [data, setData] = useState<Item[]>([]);
useEffect(() => {
// Generate some mock data for the virtual list
const generateData = (count: number): Item[] =>
Array.from({ length: count }).map((_, i) => ({
id: i,
value: `Virtual Item ${i + 1}`,
}));
setData(generateData(1000)); // Create a list with 1000 items
}, []);
return (
<div style={{ padding: 20, maxWidth: 400, border: '1px solid #ccc' }}>
<h3>rc-virtual-list Basic Usage</h3>
<p>This example demonstrates a virtualized list rendering 1000 items.</p>
<div style={{ height: 300, overflow: 'auto', border: '1px solid #eee' }}>
<List
data={data}
height={300} // The fixed height of the scrollable area
itemHeight={30} // The estimated height of a single list item
itemKey="id" // Unique key property for each item
>
{(item: Item) => (
<div
key={item.id} // Essential for React to correctly manage list elements
style={{
padding: '8px 16px',
borderBottom: '1px solid #f0f0f0',
lineHeight: '1.5'
}}
>
{item.value}
</div>
)}
</List>
</div>
</div>
);
};
export default VirtualizedListExample;