Javascript React虚拟化故障理解OverscanindiceGetter

Javascript 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

我目前正在使用React Virtualized来虚拟化列表。需要注意的是,我的列表实际上是一个网格布局,我的组件返回语句如下所示:

因此,该列表实际上最终呈现网格格式。下面的屏幕截图显示了输出atm

[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]