React Virtualized 无法理解 overscanIndicesGetter

问题描述

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

所以列表实际上最终呈现网格格式。无论如何,下面的屏幕截图说明了输出 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,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,items.length,hasMore,);

      return (
        <InfiniteLoader
          ref={infiniteLoaderRef}
          rowCount={rowCount}
          isRowLoaded={({ index }) => {
            const indexes = generateIndexesForRow(
              index,);

            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,).map((itemIndex) => items[itemIndex]);

                      return (
                        <ListRow style={style} key={key} ref={gridRowRef}>
                          {itemsForRow.map((item,itemIndex) => (
                            <ListItem key={itemIndex}>
                              {children(
                                item,itemsForRow.length,)}
                            </ListItem>
                          ))}
                        </ListRow>
                      );
                    }}
                    norowsRenderer={norowsRenderer}
                  />
                </>
              )}
            </WindowScroller>
          )}
        </InfiniteLoader>
      );
    }}
  </AutoSizer>
</>

);

孩子的渲染道具调用一个组件来渲染我的项目:

  const renderFunc = (item,isScrolling) => {
    return isVisible ? (
      <Item
        key={item.id}
        item={item}
      />
    ) : (
      <DummyItem />
    );
  };

但是,我的 isVisible 变量(在 react-virtualised 内部生成)被传递到函数中似乎有点过早地返回 false。

这会导致滚动时出现以下行为:

visual of problem

换句话说,即使在缓慢滚动时,我的过扫描也不够渴望 - 这样 isVisible 需要很长时间才能返回 true 我强烈怀疑这是由于我的布局造成的。

切入正题,仔细阅读 -(正确或错误)我认为可能需要调整过扫描索引获取器,请参阅此处:https://github.com/bvaughn/react-virtualized/blob/master/docs/Grid.md#overscanindicesgetter

但是,尽管我一无所知,但我无法完全了解该文档以确切了解它在做什么,以及可能需要做什么来解决问题以使我的过扫描更加渴望。您会注意到 overscanRowCount={96} 已经添加到列表中,我认为即使在低滚动速度下,高数字也应该足以让组件使用额外的 html .. 因此我认为可能 overscanIndicesGetter 是我的问题的关键。

感谢任何帮助,即使它帮助我了解 overscanIndicesGetter 函数以及它在幕后做了什么。我尝试使用 console.logging 一些内部变量,但我仍然不明智,因为它的输出似乎波动很大。

解决方法

1、尝试使用其他库然后react-virtualized。我建议[react-virtual][1]。边界大小要小得多,并且使用 React.FC。 (现代反应)。
2,我不确定您是否应该混合使用 virtual-listisVisible

解决方案:

结构如下:

[ITEM] [ITEM] [ITEM] [ITEM]
[ITEM] [ITEM] [ITEM] [ITEM]
[ITEM] [ITEM] [ITEM] [ITEM]

是一个好的开始。在这种情况下,您还必须跟踪容器 width 和每个 item 宽度。 宽度这个逻辑,你可以按照以下步骤操作:

  • 跟踪 rowcolumn 大小。 (marshaledList)。
  • 创建 rowVirtualizercolumnVirtualizer。 (取决于 marshaledList)。
  • 在两者之间设置一个 gap
  • 设置 listgrid 的样式。
  • 显示 rowVirtualizercolumnVirtualizer 元素。

现场演示(处理 20k 个元素):https://codesandbox.io/s/naughty-kepler-vh70n?file=/src/App.js:2501-2506

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...