React components for efficiently rendering large lists and tabular data
—
The essential components for rendering large datasets efficiently through virtualization.
A virtualized list component that renders only visible rows for optimal performance with large datasets.
/**
* Efficiently renders large lists using virtualization
* @param props - List configuration
*/
function List(props: {
/** Aria label for accessibility */
'aria-label'?: string;
/** Remove fixed height constraint for use with WindowScroller */
autoHeight?: boolean;
/** Optional CSS class name */
className?: string;
/** Estimated row size for initial calculations */
estimatedRowSize?: number;
/** Height constraint for list (determines visible rows) */
height: number;
/** Renderer when no rows are present */
noRowsRenderer?: () => React.Node;
/** Callback with rendered row information */
onRowsRendered?: (params: {overscanStartIndex: number, overscanStopIndex: number, startIndex: number, stopIndex: number}) => void;
/** Scroll event callback */
onScroll?: (params: {clientHeight: number, scrollHeight: number, scrollTop: number}) => void;
/** Custom overscan calculation function */
overscanIndicesGetter?: OverscanIndicesGetter;
/** Number of extra rows to render for smooth scrolling */
overscanRowCount?: number;
/** Fixed height or dynamic height function */
rowHeight: number | ((params: {index: number}) => number);
/** Row rendering function */
rowRenderer: (params: {index: number, key: string, style: object}) => React.Node;
/** Total number of rows */
rowCount: number;
/** Scroll alignment behavior */
scrollToAlignment?: 'auto' | 'end' | 'start' | 'center';
/** Row index to scroll to */
scrollToIndex?: number;
/** Vertical scroll offset */
scrollTop?: number;
/** Inline styles */
style?: object;
/** Tab index for focus */
tabIndex?: number;
/** Width of list */
width: number;
}): React.Component;Usage Examples:
import React from 'react';
import { List } from 'react-virtualized';
// Basic list with fixed row height
function BasicList({ items }) {
const rowRenderer = ({ index, key, style }) => (
<div key={key} style={style} className="list-item">
{items[index]}
</div>
);
return (
<List
height={400}
width={300}
rowCount={items.length}
rowHeight={50}
rowRenderer={rowRenderer}
/>
);
}
// Dynamic height list
function DynamicList({ items }) {
const getRowHeight = ({ index }) => {
// Calculate height based on content
return items[index].length * 2 + 40;
};
const rowRenderer = ({ index, key, style }) => (
<div key={key} style={style} className="dynamic-item">
<h3>{items[index].title}</h3>
<p>{items[index].description}</p>
</div>
);
return (
<List
height={400}
width={300}
rowCount={items.length}
rowHeight={getRowHeight}
rowRenderer={rowRenderer}
estimatedRowSize={80}
/>
);
}A 2D virtualized grid component for rendering tabular data with both horizontal and vertical virtualization.
/**
* Core virtualized grid component for rendering 2D data
* @param props - Grid configuration
*/
function Grid(props: {
/** Aria label for accessibility */
'aria-label'?: string;
/** Remove fixed height constraint */
autoHeight?: boolean;
/** Optional CSS class name */
className?: string;
/** Total number of columns */
columnCount: number;
/** Fixed width or dynamic width function for columns */
columnWidth: number | ((params: {index: number}) => number);
/** Estimated column size for initial calculations */
estimatedColumnSize?: number;
/** Estimated row size for initial calculations */
estimatedRowSize?: number;
/** Height constraint for grid */
height: number;
/** Renderer when no content is present */
noContentRenderer?: () => React.Node;
/** Callback when cells are rendered */
onSectionRendered?: (params: {columnStartIndex: number, columnStopIndex: number, rowStartIndex: number, rowStopIndex: number}) => void;
/** Scroll event callback */
onScroll?: (params: {clientHeight: number, clientWidth: number, scrollHeight: number, scrollLeft: number, scrollTop: number, scrollWidth: number}) => void;
/** Custom overscan calculation function */
overscanIndicesGetter?: OverscanIndicesGetter;
/** Number of extra columns to render */
overscanColumnCount?: number;
/** Number of extra rows to render */
overscanRowCount?: number;
/** Total number of rows */
rowCount: number;
/** Fixed height or dynamic height function for rows */
rowHeight: number | ((params: {index: number}) => number);
/** Cell rendering function */
cellRenderer: (params: {columnIndex: number, key: string, rowIndex: number, style: object}) => React.Node;
/** Column index to scroll to */
scrollToColumn?: number;
/** Row index to scroll to */
scrollToRow?: number;
/** Scroll alignment for columns */
scrollToAlignment?: 'auto' | 'end' | 'start' | 'center';
/** Horizontal scroll offset */
scrollLeft?: number;
/** Vertical scroll offset */
scrollTop?: number;
/** Inline styles */
style?: object;
/** Tab index for focus */
tabIndex?: number;
/** Width of grid */
width: number;
}): React.Component;Usage Examples:
import React from 'react';
import { Grid } from 'react-virtualized';
// Basic grid with fixed cell sizes
function BasicGrid({ data }) {
const cellRenderer = ({ columnIndex, key, rowIndex, style }) => (
<div key={key} style={style} className="grid-cell">
{data[rowIndex][columnIndex]}
</div>
);
return (
<Grid
cellRenderer={cellRenderer}
columnCount={data[0].length}
columnWidth={100}
height={400}
rowCount={data.length}
rowHeight={50}
width={600}
/>
);
}
// Spreadsheet-like grid with custom sizing
function SpreadsheetGrid({ rows, columns }) {
const getColumnWidth = ({ index }) => {
return columns[index].width || 100;
};
const cellRenderer = ({ columnIndex, key, rowIndex, style }) => (
<div
key={key}
style={{
...style,
border: '1px solid #ddd',
padding: '4px',
overflow: 'hidden'
}}
>
{rows[rowIndex][columns[columnIndex].key]}
</div>
);
return (
<Grid
cellRenderer={cellRenderer}
columnCount={columns.length}
columnWidth={getColumnWidth}
height={400}
rowCount={rows.length}
rowHeight={35}
width={800}
overscanColumnCount={2}
overscanRowCount={5}
/>
);
}A table component with fixed headers and virtualized rows, optimized for displaying structured data.
/**
* Table component with fixed headers and virtualized rows
* @param props - Table configuration
*/
function Table(props: {
/** Aria label for accessibility */
'aria-label'?: string;
/** Aria labelledby for accessibility */
'aria-labelledby'?: string;
/** Remove fixed height constraint */
autoHeight?: boolean;
/** Column components defining table structure */
children: Column[];
/** Optional CSS class name */
className?: string;
/** Disable header rendering */
disableHeader?: boolean;
/** Estimated row size for calculations */
estimatedRowSize: number;
/** CSS class for inner Grid element */
gridClassName?: string;
/** Inline style for inner Grid element */
gridStyle?: object;
/** CSS class for column headers */
headerClassName?: string;
/** Fixed height of header row */
headerHeight: number;
/** Custom header row renderer */
headerRowRenderer?: (params: {className: string, columns: React.Node[], style: object}) => React.Node;
/** Inline style for headers */
headerStyle?: object;
/** Height constraint for table */
height: number;
/** Optional element ID */
id?: string;
/** Renderer when no rows are present */
noRowsRenderer?: () => React.Node;
/** Column click callback */
onColumnClick?: (params: {columnData: any, dataKey: string}) => void;
/** Header click callback */
onHeaderClick?: (params: {columnData: any, dataKey: string}) => void;
/** Callback when rows are rendered */
onRowsRendered?: (params: {overscanStartIndex: number, overscanStopIndex: number, startIndex: number, stopIndex: number}) => void;
/** Scroll event callback */
onScroll?: (params: {clientHeight: number, scrollHeight: number, scrollTop: number}) => void;
/** Custom overscan calculation */
overscanIndicesGetter?: OverscanIndicesGetter;
/** Number of extra rows to render */
overscanRowCount?: number;
/** Total number of rows */
rowCount: number;
/** Function to get row data by index */
rowGetter: (params: {index: number}) => object;
/** Fixed height or dynamic height function */
rowHeight: number | ((params: {index: number}) => number);
/** Custom row renderer */
rowRenderer?: (params: {className: string, columns: React.Node[], index: number, key: string, onRowClick?: function, onRowDoubleClick?: function, onRowMouseOut?: function, onRowMouseOver?: function, onRowRightClick?: function, rowData: object, style: object}) => React.Node;
/** Sort callback function */
sort?: (params: {sortBy: string, sortDirection: string}) => void;
/** Current sort column */
sortBy?: string;
/** Current sort direction */
sortDirection?: 'ASC' | 'DESC';
/** Row index to scroll to */
scrollToIndex?: number;
/** Scroll alignment behavior */
scrollToAlignment?: 'auto' | 'end' | 'start' | 'center';
/** Vertical scroll offset */
scrollTop?: number;
/** Inline styles */
style?: object;
/** Tab index for focus */
tabIndex?: number;
/** Width of table */
width: number;
}): React.Component;Usage Examples:
import React from 'react';
import { Table, Column } from 'react-virtualized';
// Basic table with sortable columns
function UserTable({ users, onSort, sortBy, sortDirection }) {
const rowGetter = ({ index }) => users[index];
return (
<Table
width={800}
height={400}
headerHeight={50}
rowHeight={40}
rowCount={users.length}
rowGetter={rowGetter}
sort={onSort}
sortBy={sortBy}
sortDirection={sortDirection}
>
<Column
label="Name"
dataKey="name"
width={200}
/>
<Column
label="Email"
dataKey="email"
width={300}
/>
<Column
label="Age"
dataKey="age"
width={80}
/>
<Column
label="Status"
dataKey="status"
width={120}
cellRenderer={({ rowData }) => (
<span className={`status ${rowData.status}`}>
{rowData.status}
</span>
)}
/>
</Table>
);
}
// Advanced table with custom renderers
function ProductTable({ products }) {
const rowGetter = ({ index }) => products[index];
const priceRenderer = ({ cellData, rowData }) => (
<span className="price">
${cellData.toFixed(2)}
{rowData.onSale && <span className="sale-badge">SALE</span>}
</span>
);
const imageRenderer = ({ cellData }) => (
<img
src={cellData}
alt="Product"
style={{ width: 30, height: 30, borderRadius: '4px' }}
/>
);
return (
<Table
width={900}
height={500}
headerHeight={60}
rowHeight={50}
rowCount={products.length}
rowGetter={rowGetter}
estimatedRowSize={50}
>
<Column
label="Image"
dataKey="imageUrl"
width={60}
cellRenderer={imageRenderer}
disableSort
/>
<Column
label="Product Name"
dataKey="name"
width={250}
flexGrow={1}
/>
<Column
label="Category"
dataKey="category"
width={120}
/>
<Column
label="Price"
dataKey="price"
width={100}
cellRenderer={priceRenderer}
/>
<Column
label="In Stock"
dataKey="inStock"
width={80}
cellRenderer={({ cellData }) => cellData ? '✓' : '✗'}
/>
</Table>
);
}Install with Tessl CLI
npx tessl i tessl/npm-react-virtualized