这是无限表和无限滚动方案的混合。我发现的最好的抽象如下:
概述
创建一个包含所有子项的数组的组件。由于我们不渲染它们,因此仅分配它们并丢弃它们真的很便宜。如果 10k 分配太大,则可以改为传递一个函数,该函数采用一个范围并返回元素。<List>
<List>
{thousandelements.map(function() { return <Element /> })}
</List>
您的组件正在跟踪滚动位置,并且仅呈现视图中的子项。它在开头添加一个大的空 div,以伪造未呈现的先前项。List
现在,有趣的部分是,一旦渲染了组件,您就可以测量其高度并将其存储在.这使您可以计算垫片的高度,并知道视图中应显示多少个元素。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
这是一个无限列表的示例,使用我在此答案中描述的一些技术。这将是一些工作,但 React 绝对是实现无限列表的好方法:)