简体   繁体   English

React Virtualized - 嵌套的 WindowScroller/List

[英]React Virtualized - Nested WindowScroller/List

I'm trying to used react-virtualized to render a table with 1000+ rows of data.我正在尝试使用 react-virtualized 来呈现包含 1000 多行数据的表格。 The rows are very heavy containing multiple complex React components.这些行非常繁重,包含多个复杂的 React 组件。 input, combobox, date selector and popup menus all in one single row.输入、组合框、日期选择器和弹出菜单都在一行中。 I need the entire window to scroll these rows.我需要整个窗口来滚动这些行。

I also need to group the rows and nest them into a show/hide style accordion component.我还需要将行分组并将它们嵌套到显示/隐藏样式的手风琴组件中。

[+] Row Header 1
    row 1
    row 2
    ...
    row 1001
[+] Row Header 2
    row 1
    row 2
    ...
    row 1001

I'm unsure how to handle this use case or if React-Virtualized can handle this type of thing.我不确定如何处理这个用例,或者 React-Virtualized 是否可以处理这种类型的事情。

What I've tried:我试过的:

Use WindowScroller/AutoSizer/List components in conjunction and place this group of react-virtualized components into each of the accordions.结合使用 WindowScroller/AutoSizer/List 组件,并将这组反应虚拟化组件放入每个手风琴中。 This works but does not solve my perf.这有效,但不能解决我的性能问题。 issues because it's still too much for the browser to handle (first load is around 25 seconds and scrolling isn't usable)问题,因为浏览器仍然无法处理(第一次加载大约 25 秒并且滚动不可用)

Do I also need to use WindowScroller/AutoSizer/List components to handle the first level of Row Headers as well?我是否还需要使用 WindowScroller/AutoSizer/List 组件来处理第一级行标题?

Any ideas or examples would be much appreciated.任何想法或例子将不胜感激。

You can at least free up the UI thread for scrolling (of course an important UX principle) with web workers.您至少可以释放 UI 线程以供 Web Workers 滚动(当然这是一个重要的 UX 原则)。

Here is a medium-length discussion article with an example , a quick implementation doc (and the great matching article ), and my all-time favorite talk on the subject .这是一篇带有示例中等长度讨论文章、一个快速实现文档(以及很好的匹配文章),以及我一直以来最喜欢的关于该主题的演讲

This defers the effort from the main "UI" thread, but you can also prevent this deferment in the first place if the effort can be memoized with the useMemo() hook.这推迟了主“UI”线程的工作,但如果工作可以用useMemo()钩子记住,您也可以首先防止这种推迟。

The critical piece of react-virtualized is recomputeRowHeights you can achieve the desired results with this. react-virtualized 的关键部分是recomputeRowHeights您可以通过它获得所需的结果。

 import React, { useState, useRef, useEffect } from "react"; import { AutoSizer, Column, Table, defaultTableRowRenderer } from "react-virtualized"; const Component = ({ list }) => { const [selectedIndex, setSelectedIndex] = useState(-1); const tableRef = useRef(); const Details = ({ children, index }) => ( <div style={{ cursor: "pointer" }} onClick={() => setSelectedIndex(index)}> {children} </div> ); const _getDatum = index => list[index % list.length]; const _getRowHeight = ({ index }) => (index === selectedIndex ? 96 : 48); const rowGetter = ({ index }) => _getDatum(index); const cellRenderer = ({ rowIndex }) => { if (rowIndex !== selectedIndex) { return <Details index={rowIndex}>+</Details>; } else { return <Details index={-1}>-</Details>; } }; useEffect( () => { tableRef.current.recomputeRowHeights(); }, [selectedIndex] ); const rowRenderer = props => { const { index, style, className, key, rowData } = props; if (index === selectedIndex) { return ( <div style={{ ...style, display: "flex", flexDirection: "column" }} className={className} key={key} > {defaultTableRowRenderer({ ...props, style: { width: style.width, height: 48 } })} <div style={{ marginRight: "auto", marginLeft: 80, height: 48, display: "flex", alignItems: "center" }} > {rowData.details} </div> </div> ); } return defaultTableRowRenderer(props); }; return ( <div style={{ height: "90vh" }}> <AutoSizer> {({ width, height }) => ( <Table ref="Table" headerHeight={56} height={height} overscanRowCount={10} rowHeight={_getRowHeight} rowGetter={rowGetter} rowCount={1000} width={width} ref={tableRef} rowRenderer={rowRenderer} > <Column label="Index" cellDataGetter={({ rowData }) => rowData.length} cellRenderer={cellRenderer} dataKey="index" disableSort width={60} /> <Column dataKey="name" disableSort label="Full Name" width={120} /> </Table> )} </AutoSizer> </div> ); }; export default Component;

Here is thecodesandbox这是代码和

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM