reactjs - 使用 react-table + react-virtualized / react-window 无限加载
问题描述
我对我的桌子有以下要求:
- 表应该有固定的标题
- 它需要自动调整大小:为了使无限滚动工作,第一次获取应该获得足够的数据量,以便滚动出现。
- 表体应该作为无限加载器工作:当滚动到列表的末尾时,表体应该显示加载指示器并加载更多行
我的假设如下:
- 由于用户将滚动浏览可能的大量数据集,我应该虚拟化列表(react-virtualized 似乎是我唯一的好选择)
- 因为我们目前有 react-table 我想保留它(它具有声明表行、列、访问数据和过滤 + 排序的强大机制)
- 当我们使用材料 ui 时,我需要使用材料 ui 反应组件
- 因为 react-virtualized 有自己的 Table 组件我可以使用它,但是 react-table 有不同的渲染行和列的方式,所以我必须使用 List 组件。(react-table 分隔行和列,而 react-virtualized 直接使用列作为 Table 组件的子级)
- 我看到 react-virtualized 与名为 InfiniteLoader 的 HOC 组件一起工作,所以我也应该使用它
- 最后,我需要我的列不要因为它有更多的文本(即具有动态高度)而被弄乱。因此,我尝试为此使用 CellMeasurer。
在这个沙箱中可以看到我能够实现的目标 https://codesandbox.io/s/react-table-infinite-mzkkp?file=/src/MuiTable.js (我不能在这里提供代码,因为它很大)
所以,一般来说,我可以让 React-virtualized 中的 Autosizer、CellMeasurer 和 List 组件正常工作。我被困在无限滚动部分。我在官方文档上看到了示例,但它似乎有点反模式(直接突变状态根本不是一件好事)
所以我试图达到类似的结果,但是如果你能看到,我的 loadMore 函数由于某种原因触发得太早了。它导致几乎每个滚动事件都发送请求。
任何帮助深表感谢。
我已经尝试过的:
- 使用 react-window 而不是 react-virtualized 它仅适用于简单的用例,并且由于单元格的动态大小而失败。
- 使用 react-inifnite-scrollcomponent(https://www.npmjs.com/package/react-infinite-scroll-component)它适用于整个页面(无法制作“粘性”标题,无法呈现加载指示器作为表体,它颂歌对长列表没有任何优化)
- 使用 react-virtualized 中的 Table 组件。我无法使其与 react-table 一起工作(因为 react-virtualized 中的 Table 组件似乎直接将 Cells 渲染为 Table 组件的子级。我知道它具有 renderRow 功能,但这意味着两个不同的地方,而 react-table 有
<TableRow
{...row.getRowProps({
style
})}
component="div"
>
{row.cells.map((cell) => {
return (
<TableCell {...cell.getCellProps()} component="div">
{cell.render("Cell")}
</TableCell>
);
})}
</TableRow>
此外,尚不清楚如何以这种方式呈现自定义过滤器。
解决方案
我知道这不是您要寻找的答案,但我建议使用 anIntersectionObserver
而不是 virtualize 库。react-virtualized 不适用于动态/响应大小的元素。IntersectionObserver
是一个本机浏览器 api,可以检测元素何时进入视口,而无需提供元素大小。
您可以轻松地将它与react-intersection-observer之类的 react 库一起使用,该库具有一个InView
组件和一个useInView
钩子,尽管这需要用InView
. IntersectionObserver 的性能往往比基于滚动事件的解决方案(如 react-virtualized)要好,但如果您有 1000 多个观察者,这可能会降低性能。
你也可以使用像intersection-observer-admin这样的东西,它将所有的观察者集中到一个类似于 react SyntheticEvent 的实例中。您希望将其集成到类似React.useContext
或 redux 之类的东西中。
推荐阅读
- specflow - 无法在代码中获得正确的 SpecFlow+ 目标值
- java - 重载子类的构造函数
- css - 如何用图像填充形状?
- php - Laravel 5.8通过mailgun发送邮件不起作用
- c - getchar() 在创建字符串数组时不读取空格?
- jquery - 语义-ui:获取下拉列表的值以发送到 api
- google-apps-script - 如何使用 Google Apps 脚本在 Google 幻灯片中添加新的自定义布局?
- ruby-on-rails - 数据库设计:处理可用性
- html - 如何使用粘贴到占位符并由提交按钮触发的链接来抓取网站
- xml - XSLT 1.0 排序帮助