MRT logoMaterial React Table

Virtualized Example

Material React Table has a built-in virtualization features (via @tanstack/react-virtual) that allows you to render a large number of rows or columns without major performance issues that you would normally see with a large number of DOM elements.

Try out the performance of the table below with 10,000 rows and over a dozen columns! Filtering, Search, and Sorting also maintain usable performance.

Be sure to also check out the full virtualization feature guide docs to learn about both Row and Column Virtualization.

NOTE: You should only enable row virtualization if you have a large number of rows or columns. Depending on the size of the table, if you are rendering fewer than a couple dozen rows at a time, you will actually just be adding extra overhead to the table renders. Virtualization only becomes necessary when you have over 50 rows or so at the same time with no pagination or dozens of columns.

More Examples

Demo

Open StackblitzOpen Code SandboxOpen on GitHub

Source Code

1import { useEffect, useMemo, useRef, useState } from 'react';
2import {
3 MaterialReactTable,
4 useMaterialReactTable,
5 type MRT_ColumnDef,
6 type MRT_SortingState,
7 type MRT_Virtualizer,
8} from 'material-react-table';
9import { makeData, type Person } from './makeData';
10
11const Example = () => {
12 const columns = useMemo<MRT_ColumnDef<Person>[]>(
13 //column definitions...
90 );
91
92 //optionally access the underlying virtualizer instance
93 const rowVirtualizerInstanceRef =
94 useRef<MRT_Virtualizer<HTMLDivElement, HTMLTableRowElement>>(null);
95
96 const [data, setData] = useState<Person[]>([]);
97 const [isLoading, setIsLoading] = useState(true);
98 const [sorting, setSorting] = useState<MRT_SortingState>([]);
99
100 useEffect(() => {
101 if (typeof window !== 'undefined') {
102 setData(makeData(10_000));
103 setIsLoading(false);
104 }
105 }, []);
106
107 useEffect(() => {
108 //scroll to the top of the table when the sorting changes
109 try {
110 rowVirtualizerInstanceRef.current?.scrollToIndex?.(0);
111 } catch (error) {
112 console.error(error);
113 }
114 }, [sorting]);
115
116 const table = useMaterialReactTable({
117 columns,
118 data, //10,000 rows
119 defaultDisplayColumn: { enableResizing: true },
120 enableBottomToolbar: false,
121 enableColumnResizing: true,
122 enableColumnVirtualization: true,
123 enableGlobalFilterModes: true,
124 enablePagination: false,
125 enableColumnPinning: true,
126 enableRowNumbers: true,
127 enableRowVirtualization: true,
128 muiTableContainerProps: { sx: { maxHeight: '600px' } },
129 onSortingChange: setSorting,
130 state: { isLoading, sorting },
131 rowVirtualizerInstanceRef, //optional
132 rowVirtualizerOptions: { overscan: 5 }, //optionally customize the row virtualizer
133 columnVirtualizerOptions: { overscan: 2 }, //optionally customize the column virtualizer
134 });
135
136 return <MaterialReactTable table={table} />;
137};
138
139export default Example;
140

View Extra Storybook Examples