Javascript React虚拟化故障理解OverscanindiceGetter
我目前正在使用React Virtualized来虚拟化列表。需要注意的是,我的列表实际上是一个网格布局,我的组件返回语句如下所示: 因此,该列表实际上最终呈现网格格式。下面的屏幕截图显示了输出atmJavascript React虚拟化故障理解OverscanindiceGetter,javascript,reactjs,react-virtualized,Javascript,Reactjs,React Virtualized,我目前正在使用React Virtualized来虚拟化列表。需要注意的是,我的列表实际上是一个网格布局,我的组件返回语句如下所示: 因此,该列表实际上最终呈现网格格式。下面的屏幕截图显示了输出atm [ITEM] [ITEM] [ITEM] [ITEM] [ITEM] [ITEM] [ITEM] [ITEM] [ITEM] [ITEM] [ITEM] [ITEM] 取决于工作空间的大小。AutoResizer会调整我的(虚拟)网格中有多少列,这一切都很顺利 const getMaxItems
[ITEM] [ITEM] [ITEM] [ITEM]
[ITEM] [ITEM] [ITEM] [ITEM]
[ITEM] [ITEM] [ITEM] [ITEM]
取决于工作空间的大小。AutoResizer会调整我的(虚拟)网格中有多少列,这一切都很顺利
const getMaxItemsAmountPerRow = (rowWidth, itemWidth) => {
return Math.max(Math.floor(rowWidth / itemWidth), 1);
};
const generateIndexesForRow = (rowIndex, rowWidth, itemWidth, itemsAmount) => {
const result = [];
const maxItemsPerRow = getMaxItemsAmountPerRow(rowWidth, itemWidth);
const startIndex = rowIndex * maxItemsPerRow;
for (
let i = startIndex;
i < Math.min(startIndex + maxItemsPerRow, itemsAmount);
i += 1
) {
result.push(i);
}
return result;
};
const getRowsAmount = (rowWidth, itemWidth, itemsAmount, hasMore) => {
const maxItemsPerRow = getMaxItemsAmountPerRow(rowWidth, itemWidth);
const returnVal = Math.ceil(itemsAmount / maxItemsPerRow) + (hasMore ? 1 : 0);
return returnVal;
};
return (
<>
<AutoSizer disableHeight>
{({ width: rowWidth }) => {
const rowCount = getRowsAmount(
rowWidth,
itemWidth,
items.length,
hasMore,
);
return (
<InfiniteLoader
ref={infiniteLoaderRef}
rowCount={rowCount}
isRowLoaded={({ index }) => {
const indexes = generateIndexesForRow(
index,
rowWidth,
itemWidth,
items.length,
);
const allItemsLoaded = indexes.length > 0;
return !hasMore || allItemsLoaded;
}}
loadMoreRows={loadMoreRows}
>
{({ onRowsRendered }) => (
<WindowScroller>
{({ registerChild }) => (
<>
<List
height={calcGridHeight()}
width={rowWidth}
rowCount={rowCount}
overscanRowCount={96}
ref={registerChild}
rowHeight={itemHeight}
onRowsRendered={onRowsRendered}
rowRenderer={({
index,
style,
key,
isVisible,
isScrolling,
}) => {
const itemsForRow = generateIndexesForRow(
index,
rowWidth,
itemWidth,
items.length,
).map((itemIndex) => items[itemIndex]);
return (
<ListRow style={style} key={key} ref={gridRowRef}>
{itemsForRow.map((item, itemIndex) => (
<ListItem key={itemIndex}>
{children(
item,
isVisible,
isScrolling,
itemsForRow.length,
)}
</ListItem>
))}
</ListRow>
);
}}
noRowsRenderer={noRowsRenderer}
/>
</>
)}
</WindowScroller>
)}
</InfiniteLoader>
);
}}
</AutoSizer>
</>
const getMaxItemsAmountPerRow=(行宽,项宽)=>{
返回Math.max(Math.floor(rowWidth/itemWidth),1);
};
const generateIndexError=(行索引、行宽度、项宽度、项计数)=>{
常量结果=[];
const maxItemsPerRow=GetMaxItemsSamountPerrow(rowWidth,itemWidth);
const startIndex=rowIndex*maxItemsPerRow;
为了(
设i=startIndex;
i{
const maxItemsPerRow=GetMaxItemsSamountPerrow(rowWidth,itemWidth);
const returnVal=Math.ceil(itemsAmount/maxItemsPerRow)+(hasMore?1:0);
返回值;
};
返回(
换言之,我的overscan即使在缓慢滚动时也不够急切,以至于isVisible
需要很长时间才能返回true,我强烈怀疑这是由于我的布局造成的
为了切入正题,从阅读(正确或错误)我认为可能需要调整超扫描指数,请参见此处:
然而,尽管我很无知,但我无法理解这个文档的全部内容,也无法理解它到底在做什么,也无法理解我需要做些什么来解决问题,从而使我的overscan变得更加迫切。您会注意到overscanRowCount={96}已经被添加到列表中,我会认为,即使在滚动速度很慢的情况下,高数字也足以让组件使用额外的html。因此,我认为潜在的overscanidesgetter
是我问题的关键
感谢您的任何帮助,即使这有助于我了解OverCanindiceGetter函数以及它在引擎盖下的作用。我尝试了console。记录了一些内部变量,但我仍然不知道,因为它的输出似乎波动很大。1,尝试使用其他库,然后反应虚拟化
。我建议[react virtual][1]
。边界大小要小得多,使用react.FC
(现代react)。
2、我不确定是否应该混合使用虚拟列表
,而是可见的
解决方案:
结构如下:
[ITEM] [ITEM] [ITEM] [ITEM]
[ITEM] [ITEM] [ITEM] [ITEM]
[ITEM] [ITEM] [ITEM] [ITEM]
这是一个很好的开始。在这种情况下,您还必须跟踪容器宽度
,以及每个项目
宽度。
根据此逻辑,您可以执行以下步骤:
- 跟踪
行
和列
大小。(封送列表
)
- 创建
行虚拟化器
和列虚拟化器
(取决于封送列表
)
- 设置之间的
间隙
- 设置
列表
和网格
的样式
- 显示
行虚拟化器
和列虚拟化器
元素
现场演示(使用20k元素):https://codesandbox.io/s/naughty-kepler-vh70n?file=/src/App.js:2501-2506
我不确定问题出在哪里,但我猜您遇到了性能问题,正在等待改进?想知道是否可以使用此库从api获取动态数据?如何确定何时获取?当然可以。只需将元素
替换为一些api
响应(useAsync,或一些状态处理程序,但不是简单的变量
),并显示您所需的每个项目的属性。@Squiggs它对您有帮助吗?不幸的是,没有,我无法让它使用带有异步数据调用的动态分页。文档上的演示也不起作用。
[ITEM] [ITEM] [ITEM] [ITEM]
[ITEM] [ITEM] [ITEM] [ITEM]
[ITEM] [ITEM] [ITEM] [ITEM]