React Virtualized Components
react-virtualized is a React library providing a collection of high-performance components designed for efficiently rendering large datasets, such as extensive lists and complex tables. It employs a "windowing" or "virtualization" technique, rendering only the rows or cells currently visible in the viewport, which drastically improves performance and reduces memory consumption in data-heavy applications. The current stable version is 9.22.6. Recent releases primarily focus on updating peer dependencies to maintain compatibility with newer React versions (up to React 19) and addressing minor bug fixes or security enhancements like Trusted Types support, indicating a maintenance phase rather than active feature development. Key differentiators include its comprehensive suite of components (List, Table, Grid, Collection), flexible sizing options, and a robust architecture optimized for minimizing DOM nodes and reflows.
Common errors
-
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components)
cause This error typically occurs when React cannot resolve the component imported from `react-virtualized`. This can be due to incorrect import paths, a mismatched React version, or multiple instances of React loaded in the application.fixVerify that `react` and `react-dom` peer dependencies are met. Ensure you are using named imports correctly (e.g., `import { List } from 'react-virtualized'`). Check your bundler configuration for potential duplicate React instances. -
TypeError: Cannot read properties of undefined (reading 'length')
cause Occurs when the data source (e.g., `list` prop for `List` or `rowCount`) passed to a virtualized component is `undefined` or `null` instead of an array or a number, especially during initial render or asynchronous data loading.fixEnsure that the data array or `rowCount` is always initialized, even if empty, before rendering the virtualized component. For asynchronous data, conditionally render the component after data is loaded or provide a default empty array/zero count. -
Uncaught TypeError: Cannot read properties of null (reading 'scrollTop')
cause This error often indicates that you're attempting to access a method or property on a `react-virtualized` component instance (e.g., via a ref) before the component has been mounted to the DOM or if the ref is not properly assigned.fixEnsure that any imperative calls on component refs are made only after the component has mounted (e.g., within `useEffect` with an empty dependency array or after a render). Double-check ref assignment and `null` checks before accessing ref properties.
Warnings
- breaking Recent minor versions (9.22.4, 9.22.6) updated peer dependencies to include React 17, 18, and 19. While this aims for compatibility, ensure your project's React version aligns with these requirements to avoid potential build or runtime issues due to mismatched React contexts.
- gotcha Achieving optimal performance with virtualized lists often requires stable props. Frequent changes to `rowHeight`, `rowCount`, or `rowRenderer` (if not memoized) can negate the performance benefits of virtualization, leading to unnecessary re-renders.
- gotcha Incorrectly configuring `width` and `height` props for `List`, `Table`, or `Grid` components can result in blank content or unexpected scroll behavior. These components require explicit dimensions or need to be wrapped in a container that provides them (e.g., `AutoSizer`).
Install
-
npm install react-virtualized -
yarn add react-virtualized -
pnpm add react-virtualized
Imports
- List
const List = require('react-virtualized')import { List } from 'react-virtualized' - Table
import Table from 'react-virtualized/dist/commonjs/Table'
import { Table, Column } from 'react-virtualized' - AutoSizer
import { AutoSizer } from 'react-virtualized/lib/AutoSizer'import { AutoSizer } from 'react-virtualized' - ListRowRenderer
type ListRowRenderer = ({ index, key, style, parent }: ListRowProps) => React.ReactNodeimport { ListRowRenderer } from 'react-virtualized'
Quickstart
import React, { useRef, useCallback } from 'react';
import { List, AutoSizer, ListRowRenderer } from 'react-virtualized';
import 'react-virtualized/styles.css'; // Essential for basic styling
interface Item {
id: number;
name: string;
description: string;
}
const generateData = (count: number): Item[] => {
const data: Item[] = [];
for (let i = 0; i < count; i++) {
data.push({
id: i,
name: `Item ${i}`,
description: `This is the description for item number ${i}. It can be quite long, demonstrating content within a virtualized row.`
});
}
return data;
};
const items = generateData(10000); // Generate 10,000 dummy items
function MyVirtualizedList() {
const listRef = useRef<List>(null);
const rowRenderer: ListRowRenderer = useCallback(({ index, key, style }) => {
const item = items[index];
return (
<div key={key} style={{ ...style, borderBottom: '1px solid #eee', padding: '10px' }}>
<h3 style={{ margin: 0 }}>{item.name}</h3>
<p style={{ margin: '5px 0 0' }}>{item.description}</p>
</div>
);
}, [items]); // Dependencies for useCallback to prevent unnecessary re-renders
return (
<div style={{ width: '100%', height: '500px' }}>
<AutoSizer>
{({ width, height }) => (
<List
ref={listRef}
width={width}
height={height}
rowCount={items.length}
rowHeight={80} // Fixed height for simplicity; dynamic heights require more complex setup
rowRenderer={rowRenderer}
overscanRowCount={3} // Render a few extra rows for smoother scrolling
/>
)}
</AutoSizer>
</div>
);
}
export default MyVirtualizedList;