javascript - React Virtualized Grid + Infinite Loader + Cell Measurer
问题描述
我正在尝试创建一个相当大的网格(大约 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,这可能会导致性能下降。问题是当用大量行水平滚动时,粘性标题越界(不是 onscroll 的缓慢性能,它只是计算粘性网格尺寸不正确):
也许我错误地使用了 cellMeasurer?还是有些道具设置错了?有人有类似的问题吗?
解决方案
推荐阅读
- javascript - 以角度结束http请求
- java - 从 GuavaCache 迁移到 EhCache (Spring Boot)
- vb.net - 在 vb.net 解决方案资源管理器中设置 Kleopatra
- php - php fgetcsv 返回带空格的字符串数组
- javascript - onDrop 事件无法正常工作 React?
- c# - 如果 Bot 需要时间来响应,它会自动调用 MessageController 并使用先前的消息
- javascript - scrollIntoView 在边缘不平滑
- terraform - 基于另一个变量的引用变量
- python-3.x - ML 新手第一次尝试使用 SVM 和 SVR 出现一些语法/转置错误
- android - Xamarin Android 应用程序 504 错误