【问题标题】:How to render whole Grid in DOM if I need in react-virtualized?如果我需要反应虚拟化,如何在 DOM 中渲染整个网格?
【发布时间】:2017-03-13 14:26:04
【问题描述】:

我正在构建一个 React 应用程序,我有多个 Grid 组件,结合 ScrollSync,如下所示:

<ScrollSync>
...
   <Grid />
   <Grid />
...
</ScrollSync>

看起来像这样:

他们正在正确滚动,一个正在跟随另一个。但是,我需要 GRID 1 始终在 DOM 中完全呈现。

Grid 的 overscanRowCount 选项没有帮助,因为它只给了我 n 行,但只在滚动方向上。

例如,如果我渲染了 10 行,并且我将 overscanRowCount 设置为 6 - 如果我向下滚动,我将有 10 + 底部 6 行,如果我滚动到顶部,我将有 10 + 6 顶部行。

我为什么需要它?我的应用如下所示:

因此,例如,当“prod5”项目离开 DOM 时,那条蓝线也会丢失,每一行都是从行项目到顶部。

对我来说不错的选择是渲染 n 行顶部和底部行,或者简单地 - 全部呈现。任何解决方案或解决方法?我搜索了很多,找不到任何有用的东西。

【问题讨论】:

  • 为什么总是需要渲染?你想解决什么问题?
  • 我更新了问题。
  • 一种可能性:不要对左侧网格使用 react-virtualized 和 implement ScrollSync yourself
  • 另一种可能性:将蓝线渲染为段(每个单元格一个段)并预处理您的数据,使传递给每个单元格的道具包括例如hasBlueLineSegment 财产。
  • 你看过overscanIndicesGetter prop吗?如果您知道单元格的总数,您似乎可以实现一个始终返回 { overscanStartIndex: 0, overscanStopIndex: totalNumberOfCells } 的函数。

标签: javascript reactjs react-virtualized


【解决方案1】:

我不是 react-virtualized 方面的专家,但似乎定义自定义 overscanIndicesGetter 函数可能是最简单的解决方案。每the docs

overscanIndicesGetter

这是一个高级属性。该功能负责 计算在 a 之前和之后要过扫描的单元数 规定范围。默认情况下,React Virtualized 优化了 单元格根据滚动方向进行过扫描。如果你想 自定义此行为,您可能需要分叉 defaultOverscanIndicesGetter 功能。

在下面的 sn-p 中,我定义了一个函数,它总是返回 0 的 overscanStartIndex 和等于最后一个索引的 overscanStopIndex

const overscanIndicesGetter = ({cellCount}) => ({
  overscanStartIndex: 0,
  overscanStopIndex: cellCount - 1,
});

查看您的开发人员工具,您会发现它确实渲染了所有 1,000 个单元格。

const { Grid } = window.ReactVirtualized;

const data = Array.from(new Array(1000)).map((_, i) => i);

const Cell = ({key, rowIndex, style}) =>
  <div key={key} style={style}>{data[rowIndex]}</div>;

const overscanIndicesGetter = ({cellCount}) => ({
  overscanStartIndex: 0,
  overscanStopIndex: cellCount - 1,
});

const App = ({data}) => (
  <Grid
    cellRenderer={Cell}
    columnCount={1}
    columnWidth={100}
    rowCount={data.length}
    rowHeight={30}
    height={300}
    width={300}
    overscanIndicesGetter={overscanIndicesGetter}
  />
);

ReactDOM.render(<App data={data}/>, document.querySelector('div'));
<link rel="stylesheet" src="https://unpkg.com/react-virtualized@9.2.2/styles.css"></link>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js"></script>
<script src="https://unpkg.com/react-virtualized@9.2.2/dist/umd/react-virtualized.js"></script>
<div></div>

如果你愿意,你可以尝试让它更智能。例如,如果您能够根据可见单元格的索引计算下一个“prod”单元格(即确定可见单元格是否有蓝线的单元格)的索引,则可以将函数修改为返回overscanStopIndex 的索引。 built-in defaultOverscanIndicesGetter function 记录了您的函数将收到的所有值。

/**
 * Calculates the number of cells to overscan before and after a specified range.
 * This function ensures that overscanning doesn't exceed the available cells.
 *
 * @param cellCount Number of rows or columns in the current axis
 * @param scrollDirection One of SCROLL_DIRECTION_BACKWARD or SCROLL_DIRECTION_FORWARD
 * @param overscanCellsCount Maximum number of cells to over-render in either direction
 * @param startIndex Begin of range of visible cells
 * @param stopIndex End of range of visible cells
 */

如果您有大量数据,不妨花时间看看您能用这些数据做什么。

【讨论】:

  • 这是您所描述内容的正确答案 ^ 不要渲染左侧网格中的所有行。这对性能不利。索引 getter 应该是最简单的解决方案。或者,您可以提供自己的 cellRangeRenderer 来装饰默认值并管理您的连接线。在文档中也有一个扩展该道具的基本示例。
  • 它很有效,并且也提供了让它更智能的好建议。我会让它在应用程序的第一个版本中像这样运行 - 到目前为止性能非常好。更重要的是右网格不在 DOM 中,左网格不是问题,没有那么多项目。有一天,我将实现计算蓝线可见所需的特定数量。再次感谢!
猜你喜欢
  • 2020-03-24
  • 2017-07-29
  • 2016-09-06
  • 2018-01-22
  • 2018-01-06
  • 2021-04-28
  • 2018-04-28
  • 2014-09-27
  • 2017-01-06
相关资源
最近更新 更多