ReactJS:双向无限滚动建模

noa*_*oah 113 html javascript infinite-scroll reactjs

我们的应用程序使用无限滚动来导航异类项目的大型列表.有一些皱纹:

  • 我们的用户通常拥有10,000个项目的列表,需要滚动3k +.
  • 这些是丰富的项目,因此在浏览器性能变得不可接受之前,我们只能在DOM中使用几百个.
  • 这些物品的高度各不相同.
  • 这些项目可能包含图像,我们允许用户跳转到特定日期.这很棘手,因为用户可以跳转到列表中我们需要在视口上方加载图像的位置,这会在加载时推送内容.未能处理这意味着用户可能会跳转到某个日期,但随后会转移到更早的日期.

已知的不完整解决方案:

我不是在寻找完整解决方案的代码(虽然那会很棒.)相反,我正在寻找"反应方式"来模拟这种情况.滚动位置是否状态?我应该跟踪什么状态来保留我在列表中的位置?当我在渲染的底部或顶部附近滚动时,我需要保持什么状态才能触发新的渲染?

Vje*_*eux 113

这是无限表和无限滚动场景的混合.我发现的最好的抽象是:

概观

创建<List>一个包含所有子项数组的组件.由于我们不渲染它们,因此分配它们并丢弃它们真的很便宜.如果10k分配太大,您可以改为传递一个取一个范围并返回元素的函数.

<List>
  {thousandelements.map(function() { return <Element /> })}
</List>
Run Code Online (Sandbox Code Playgroud)

您的List组件正在跟踪滚动位置,并且只呈现视图中的子项.它在开头添加一个大的空div来伪造之前未渲染的项目.

现在,有趣的是,一旦Element渲染了一个组件,你就可以测量它的高度并将其存储在你的中List.这使您可以计算间隔物的高度,并知道应该在视图中显示多少元素.

图片

你说的是,当图像加载时,它们会让所有东西"跳"下来.解决方案是在img标记中设置图像尺寸:<img src="..." width="100" height="58" />.这样,浏览器在知道要显示的大小之前不必等待下载它.这需要一些基础设施,但它确实值得.

如果您无法事先知道大小,则将onload侦听器添加到图像中,并在加载图像时测量其显示的尺寸并更新存储的行高并补偿滚动位置.

跳跃随机元素

如果你需要跳转列表中的随机元素,那么滚动位置需要一些技巧,因为你不知道它们之间的元素大小.我建议你做的是平均你已经计算过的元素高度,并跳转到最后已知高度的滚动位置+(元素数量*平均值).

由于这不准确,当你回到最后一个已知的好位置时,它会引起问题.发生冲突时,只需更改滚动位置即可修复它.这会稍微移动滚动条,但不应该影响他/她.

反应细节

您希望为所有渲染元素提供一个键,以便在渲染过程中维护它们.有两种策略:(1)只有n个键(0,1,2,... n),其中n是你可以显示的最大元素数,并使用它们的位置模n.(2)每个元素有一个不同的键.如果所有元素共享相似的结构,则使用(1)重用其DOM节点是很好的.如果他们不这样做则使用(2).

我只有两个React状态:第一个元素的索引和显示的元素数量.当前滚动位置和所有元素的高度将直接附加到this.在使用时,setState您实际上正在进行重新渲染,只有在范围发生变化时才会发生.

这是一个使用我在这个答案中描述的一些技术的无限列表的示例http://jsfiddle.net/vjeux/KbWJ2/9/.这将是一些工作,但React绝对是实现无限列表的好方法:)

  • 这是一个很棒的技术.谢谢!我让它在我的一个组件上工作.但是,我有另一个组件,我想将其应用于此,但行没有一致的高度.我正在努力扩充你的例子以计算displayEnd/visibleEnd来解释不同的高度......除非你有更好的想法? (4认同)
  • 我已经[更新了小提琴](http://jsfiddle.net/aknuds1/cchujfb1/),我认为它应该是一样的.有人在乎验证吗?@Meglio (3认同)