我正在尝试创建一个很大的网格(大约40列,超过1k行-动态宽度),并带有粘性标头和无限加载程序以追加更多行。我已经在示例中使用了它,但是当获得更多行时,性能会急剧下降-可能是因为动态宽度和cellmeasurer必须检查所有内容。以下是我用于打印表格的组件的代码:
import * as React from "react";
import { Grid, CellMeasurer, AutoSizer, ScrollSync, CellMeasurerCache, InfiniteLoader } from 'react-virtualized';
interface VirtualizedTableProps {
loadMore?: (IndexRange: any) => Promise<any>
data: any,
rowHeight?: number,
headerHeight?: number,
headers: string[],
cellClassName?: string,
headerCellClassName?: string,
isFullHeight?: boolean,
getCellContent: Function
}
export class VirtualizedTable extends React.Component<VirtualizedTableProps> {
static defaultProps = {
rowHeight: 37,
headerHeight: 38,
headerCellClassName: 'Virtualized-table-header',
cellClassName: 'Virtualized-table-cell',
isFullHeight: false,
loadMore: () => {},
}
cellMeasurerCache = new CellMeasurerCache({
fixedHeight: true,
minWidth: 40,
//defaultWidth: 40
});
componentDidUpdate(prevProps: VirtualizedTableProps) {
if(prevProps && this.props && prevProps.data !== this.props.data) {
this.cellMeasurerCache.clearAll();
}
}
render() {
const {
rowHeight,
headerHeight,
headers,
cellClassName,
headerCellClassName,
data,
isFullHeight,
loadMore,
getCellContent
} = this.props;
const tableHeight = data.length < 9 ? rowHeight * data.length : rowHeight * 10;
return (
<div style={{ height: '100%' }}>
<ScrollSync>
{({ onScroll, scrollLeft }) => {
return (
<AutoSizer onResize={() => { this.cellMeasurerCache.clearAll() }}>
{({ width, height }) => {
return (
<div>
<Grid
className={'Virtualized-table-header-wrapper'}
columnWidth={this.cellMeasurerCache.columnWidth}
columnCount={headers.length}
deferredMeasurementCache={this.cellMeasurerCache}
height={35}
overscanColumnCount={headers.length}
rowHeight={headerHeight}
rowCount={1}
scrollLeft={scrollLeft}
width={width - 17} // needs to be shorter because of the system scroll
cellRenderer={({ columnIndex, key, parent, rowIndex, style }) => {
const value = headers[columnIndex];
return (
<CellMeasurer
cache={this.cellMeasurerCache}
columnIndex={columnIndex}
key={key}
parent={parent}
rowIndex={rowIndex}
>
<div className={headerCellClassName} style={{
...style,
}}>
<span style={{ padding: '0 20px', whiteSpace: 'nowrap' }}>{value}</span>
</div>
</CellMeasurer>
);
}}
/>
<InfiniteLoader
isRowLoaded={({ index }) => !!data[index]}
loadMoreRows={loadMore}
rowCount={100000000000} // this needs to be like this
>
{({ onRowsRendered, registerChild }) => {
return (
<Grid
onSectionRendered={({ rowStartIndex, rowStopIndex }) => {
const startIndex = rowStartIndex;
const stopIndex = rowStopIndex;
onRowsRendered({ startIndex, stopIndex })
}}
ref={registerChild}
columnCount={headers.length}
columnWidth={this.cellMeasurerCache.columnWidth}
deferredMeasurementCache={this.cellMeasurerCache}
height={isFullHeight ? height - headerHeight : tableHeight }
overscanColumnCount={headers.length}
overscanRowCount={50}
rowHeight={rowHeight}
width={width}
rowCount={data.length}
onScroll={onScroll}
cellRenderer={({ columnIndex, key, parent, rowIndex, style }) => {
const conversation = data[rowIndex];
return (
<CellMeasurer
cache={this.cellMeasurerCache}
columnIndex={columnIndex}
key={key}
parent={parent}
rowIndex={rowIndex+1}
>
<div className={`${cellClassName} ${rowIndex % 2 ? 'even' : ''}`} style={{
...style,
whiteSpace: 'nowrap',
}}>
<span style={{ padding: '0 20px' }}>{getCellContent(conversation, columnIndex)}</span>
</div>
</CellMeasurer>
);
}}
/>
)
}}
</InfiniteLoader>
</div>
)
}}
</AutoSizer>
)
}}
</ScrollSync>
</div>
)
}
}
我不确定我是否按预期使用cellMeasurer,这可能会导致性能下降。问题在于,在水平滚动大量行时,粘性标头脱节(不是滚动性能慢,它只是计算出粘性网格的尺寸不正确):
也许我错误地使用了cellMeasurer?还是某些道具设置错误? 任何人都有类似的问题吗?