--- order: 30 title: en-US: Virtual list zh-CN: 虚拟列表 --- ## zh-CN 通过 `react-window` 引入虚拟滚动方案,实现 100000 条数据的高性能表格。 ## en-US Integrate virtual scroll with `react-window` to achieve a high performance table of 100,000 data. ```jsx import { VariableSizeGrid as Grid } from 'react-window'; import ResizeObserver from 'rc-resize-observer'; import classNames from 'classnames'; import { Table } from 'antd'; function VirtualTable(props) { const { columns, scroll, className } = props; const [tableWidth, setTableWidth] = React.useState(0); const widthColumnCount = columns.filter(({ width }) => !width).length; const mergedColumns = columns.map(column => { if (column.width) { return column; } return { ...column, width: Math.floor(tableWidth / widthColumnCount), }; }); const gridRef = React.useRef(); const [connectObject] = React.useState(() => { const obj = {}; Object.defineProperty(obj, 'scrollLeft', { get: () => null, set: (scrollLeft: number) => { if (gridRef.current) { gridRef.current.scrollTo({ scrollLeft }); } }, }); return obj; }); const resetVirtualGrid = () => { gridRef.current.resetAfterIndices({ columnIndex: 0, shouldForceUpdate: false, }); }; React.useEffect(() => resetVirtualGrid, []); React.useEffect(() => resetVirtualGrid, [tableWidth]); const renderVirtualList = (rawData: object[], { scrollbarSize, ref, onScroll }: any) => { ref.current = connectObject; return ( { const { width } = mergedColumns[index]; return index === mergedColumns.length - 1 ? width - scrollbarSize - 1 : width; }} height={scroll.y} rowCount={rawData.length} rowHeight={() => 54} width={tableWidth} onScroll={({ scrollLeft }) => { onScroll({ scrollLeft }); }} > {({ columnIndex, rowIndex, style }) => (
{rawData[rowIndex][mergedColumns[columnIndex].dataIndex]}
)}
); }; return ( { setTableWidth(width); }}> ); }; // Usage const columns = [ { title: 'A', dataIndex: 'key', width: 150 }, { title: 'B', dataIndex: 'key'}, { title: 'C', dataIndex: 'key'}, { title: 'D', dataIndex: 'key'}, { title: 'E', dataIndex: 'key', width: 200 }, { title: 'F', dataIndex: 'key', width: 100 }, ]; const data = []; for (let i = 0; i < 100000; i += 1) { data.push({ key: i, }); } ReactDOM.render( , mountNode, ); ```