标签: react-virtualized

如何在不向 DOM 渲染任何内容的情况下计算文本高度?

我正在利用虚拟化列表 ( react-virtualized ),其中需要我的列表项的高度并且可能会有很大差异。由于变化很大,我给库的任何高度估计都会产生糟糕的体验。

高度计算的常用方法是这样的:

const containerStyle = {
  display: "inline-block",
  position: "absolute",
  visibility: "hidden",
  zIndex: -1,
};

export const measureText = (text) => {
  const container = document.createElement("div");
  container.style = containerStyle;

  container.appendChild(text);

  document.body.appendChild(container);

  const height = container.clientHeight;
  const width = container.clientWidth;

  container.parentNode.removeChild(container);
  return { height, width };
};
Run Code Online (Sandbox Code Playgroud)

不幸的是,当您处理包含不同大小项目的超大列表时,这不是高效的。虽然可以利用缓存,但当您需要在一开始就知道总高度(所有项目组合的高度)时,即使这样做也不会很好。

经常使用的第二种解决方案是通过 HTML canvas' measureText。性能类似于上面的 DOM 操作。

就我而言,我知道以下几点:

  • 集装箱宽度
  • 字体
  • 字体大小
  • 所有填充
  • 所有边距
  • 任何和所有其他样式,如 line-height

我正在寻找的是一个数学解决方案,它可以计算高度(或非常接近的估计),这样我就不必依赖任何 DOM 操作,而且我可以随时获得高度。

我想它是这样的:

const measureText = (text, options) => {
  const { …
Run Code Online (Sandbox Code Playgroud)

html javascript dom react-virtualized

21
推荐指数
1
解决办法
706
查看次数

使用反应表+反应虚拟化/反应窗口进行无限加载

我对我的桌子有以下要求

  1. 表格应该有固定的标题
  2. 它需要自动调整大小:为了使无限滚动正常工作,第一次提取应该获得足够的数据量以便滚动出现。
  3. 表体应作为无限加载器工作:当滚动到列表末尾时表体应显示加载指示器并加载更多行

我的假设如下

  1. 由于用户将滚动浏览可能较大的数据集,我应该虚拟化列表(反应虚拟化似乎是我唯一的好选择)
  2. 因为我们目前有react-table,我想保留它(它有声明表行、列、访问数据和过滤+排序的强大机制)
  3. 当我们使用 Material ui 时,我需要使用 Material ui React 组件
  4. 因为react-virtualized有自己的Table组件,我可以使用它,但是react-table有不同的渲染行和列的方式,因此我必须使用List组件。(react-table 分隔行和列,而react-virtualized 直接使用列作为 Table 组件的子组件)
  5. 我看到react-virtualized可以与名为InfiniteLoader的HOC组件一起使用,所以我也应该使用它
  6. 最后,我需要我的列不要仅仅因为它有更多文本(即具有动态高度)而被搞乱。所以我尝试使用 CellMeasurer 来实现这一点。

我能够实现的目标可以在这个沙箱中看到 https://codesandbox.io/s/react-table-infinite-mzkkp?file=/src/MuiTable.js (我无法在这里提供代码,因为它很大)

因此,一般来说,我可以使 Autosizer、CellMeasurer 和 List 组件从反应虚拟化中正常工作。我被困在无限滚动部分。我在官方文档上看到了这个例子,但似乎有点反模式(直接突变状态根本不是一件好事)

所以我试图达到类似的结果,但是如果你能看到,我的 loadMore 函数由于某种原因触发得太早了。它导致几乎每个滚动事件都发送请求。

任何帮助深表感谢。

我已经尝试过的:

  1. 使用react-window而不是react-virtualized 它仅适用于简单的用例,并且对于动态大小的单元格会失败。
  2. 使用react-inifnite-scrollcomponenthttps://www.npmjs.com/package/react-infinite-scroll-component ))它适用于整个页面(无法制作“粘性”标题,无法将加载指示器作为表体,它对长列表没有任何优化)
  3. 使用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>
Run Code Online (Sandbox Code Playgroud)

此外,尚不清楚如何以这种方式呈现自定义过滤器。

reactjs react-virtualized react-infinite-scroll react-table-v7

17
推荐指数
1
解决办法
6054
查看次数

如何在react-virtualized autosizer中包装material-ui ListItem

我使用的是material-ui的List和ListItem组件.具体来说,我使用的是嵌套项功能.请参阅http://www.material-ui.com/#/components/list ,在页面的下半部分,您将看到嵌套列表.重点是:material-ui负责"嵌套"问题,例如缩进以及扩展/收缩箭头.

一旦我添加了很多项目,我意识到列表非常慢.所以我偶然发现了AutoSizer的反应虚拟化.问题是:在反应虚拟化中,我的代码需要为每一行提供rowRenderer函数.我不想丢失内置的材料-ui功能,可以找出嵌套项目的缩进.然而,使用AutoSizer似乎我的代码需要做自定义工作来找出缩进.我的代码也将提供扩展/合同箭头.目前它是免费的材料-ui的List/ListItem.

任何提示或建议?

谢谢

list material-ui react-virtualized

15
推荐指数
1
解决办法
2231
查看次数

具有反应虚拟化和新CellMeasurer的动态行高

我正在使用react-virualized 9与Autosizer,List和CellMeasurer组件.我需要在列表数据发生变化时更新行高.看来,自从版本9中支持React Fiber的更改以来,CellMeasurer的唯一公共方法现在是measure().大多数示例使用以前的resetMeasurementForRow()方法.当前的CellMeasurer doc似乎没有关于新公共方法的任何信息.不确定我是否忽略了某些东西,但感谢任何帮助.

const cache = new CellMeasurerCache({
  defaultHeight: 60,
  fixedWidth: true
});

<AutoSizer>
  {({ width, height }) => (
    <List
      deferredMeasurementCache={cache}
      height={height}
      ref={element => { this.list = element; }}
      rowCount={list.length}
      rowHeight={cache.rowHeight}
      rowRenderer={this.rowRenderer}
      width={width}
    />
  )}
</AutoSizer>

rowRenderer({ index, key, parent, style }) {
  return (
    <CellMeasurer
      cache={cache}
      columnIndex={0}
      key={key}
      overscanRowCount={10}
      parent={parent}
      ref={element => { this.cellMeasurer = element; }}
      rowIndex={index}
    >
      {({ measure }) => {
        this.measure = measure.bind(this);

        return <MyList index={index} data={list[index]} style={style} />;
      }}
    </CellMeasurer> …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-virtualized

15
推荐指数
1
解决办法
1万
查看次数

React Virtualized - onclick,展开Rows以获取更多详细信息

我需要打开/关闭其他行详细信息.

有没有人实现或有想法如何为每一行实现扩展/折叠功能?

reactjs react-virtualized

13
推荐指数
3
解决办法
5588
查看次数

React-virtualized,List在滚动时是Flickkering/lagging

当我滚动浏览列表时,我遇到了一些问题.还要注意底部的巨大空间.观看视频:https://vimeo.com/215349521

据我所知,我没有犯任何重大错误.但我确实相信问题是由于CellMeasurer.

Chrome版本:58.0.3029.81

class PromotionList extends Component {

constructor(props) {
    super(props);

    this.cache = new CellMeasurerCache({
        defaultHeight: 100,
        fixedWidth: true,
    });

    this.rowRenderer = this.rowRenderer.bind(this);
}

componentWillMount() {
    this.props.fetchPromotionsIfNeeded();
}

rowRenderer({ index, parent }) {
    const { promotions } = this.props;
    const data = promotions.list[index];

    return (
      <CellMeasurer
        cache={this.cache}
        columnIndex={0}
        key={uuid.v1()}
        parent={parent}
        rowIndex={index}
      >
        <BlobItem
          key={uuid.v1()}
          type={BlobTypes.promotion}
          data={data}
          onClick={this.props.onItemClick}
          index={index}
        />
      </CellMeasurer>
    );
}


render() {
    const { promotions, previewSize } = this.props;

    return (
      <List
        height={300}
        width={previewSize.width}
        rowCount={promotions.list.length} …
Run Code Online (Sandbox Code Playgroud)

reactjs react-virtualized

12
推荐指数
1
解决办法
3528
查看次数

React Virtualized Table-约8列表中输入元素的性能问题

我正在尝试创建一个8列的表,每列包含一个<input />元素。由于某些原因,我在文本输入的on change事件中遇到了延迟。将列数减少到4以下可改善体验。这可能是有道理的,但是我也尝试增加列的数量,结果发现对于10个或更多的列,体验还是很棒的。您可以检查我的超级简单React应用程序,在其中可以动态更改列数-http://com.react.table-with-inputs.s3-website.eu-central-1.amazonaws.com/

这是我的代码:

import React from 'react';
import { AutoSizer, Table, Column } from 'react-virtualized';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      numOfCols: '8',
    };
  }

  rowGetter = ({ index }) => {
    return { index };
  };

  renderHeaderCell = ({ label }) => {
    return (
      <span>{label}</span>
    );
  };

  renderCell = ({ rowIndex, columnIndex }) => {
    return (
      <input key={`input-${rowIndex}-${columnIndex}`} />
    );
  };

  render() {
    return (
      <div style={{ …
Run Code Online (Sandbox Code Playgroud)

reactjs react-virtualized

12
推荐指数
1
解决办法
234
查看次数

如何将InfiniteLoader与WindowScroller结合起来?

如何在窗口滚动条中创建无限滚动列表?(与Facebook时间线相同 - 模拟)?

下面是我尝试过的代码,但它没有按预期工作.它只显示第一个项目,之后不显示任何内容.

<div className={styles.WindowScrollerWrapper}>
    <InfiniteLoader
      isRowLoaded={this._isRowLoaded}
      loadMoreRows={this._loadMoreRows}
      rowCount={list.size}
      threshold={10}>
      {({ onRowsRendered, registerChild }) => (
        <WindowScroller>
          {({ height, isScrolling, scrollTop }) => (
            <AutoSizer disableHeight>
              {({ width }) => (

                <List
                  ref={registerChild}
                  className={styles.List}
                  autoHeight
                  height={height}
                  width={width}
                  onRowsRendered={onRowsRendered}
                  rowCount={list.size}
                  rowHeight={30}
                  rowRenderer={this._rowRenderer}
                  scrollToIndex={randomScrollToIndex}
                  />
              )}
            </AutoSizer>
          )}
        </WindowScroller>
      )}
    </InfiniteLoader>
</div>
Run Code Online (Sandbox Code Playgroud)

提前谢谢了.

更新

以下是演示的URL:https://plnkr.co/edit/akyEpZ0cXhfs2jtZgQmN

react-virtualized

11
推荐指数
1
解决办法
3084
查看次数

React-Virtualized Autosizer为VirtualScroll计算高度为0

AutoSizer的宽度给我一个合适的值,我一直得到Autosizer高度为0,这导致VirtualScroll组件不显示.但是,如果我使用disableHeight prop并为VirtualScroll提供固定的高度值(即200px),VirtualScroll会按预期显示行.谁能看到什么错了?

最终,Autosizer意味着生活在Material-ui Dialog组件中,但我也试过将autosizer简单地渲染成div.同样的问题.

render() {
return (
  <Dialog
    modal={false}
    open={this.state.open}
    onRequestClose={this.handleClose}
    contentStyle={pageOptionsDialog.body}
  >
  <div>
    <AutoSizer>
      {({ width, height }) => (
        <VirtualScroll
          id="virtualScroll"
          onRowsRendered={this.props.loadNextPage}
          rowRenderer={this.rowRenderer}
          height={height}
          rowCount={this.props.rowCount}
          rowHeight={30}
          width={width}
        />
      )}
    </AutoSizer>
  </div>
</dialog>
)}
Run Code Online (Sandbox Code Playgroud)

javascript material-ui react-virtualized

9
推荐指数
1
解决办法
4164
查看次数

JS网格性能比较

我使用angular-ui-grid(http://ui-grid.info/)来显示表格数据.总的来说,它很慢,所以我们决定使用ag-grid(https://www.ag-grid.com/).这对于常规大小的数据集来说,性能更高,更好.

但是,现在我们正在处理一些大小为100列×10,000行(~1M单元)的表格数据,并且网格的性能似乎相当慢.

我想知道是否有人使用过hypergrid(https://fin-hypergrid.github.io/core/2.0.2/) - 它似乎'解决'大cols x 大行的问题,在他们的演示中似乎在大型数据集上更快(几乎一个数量级).

hypergrid如何与ag-grid相比,或者对大数据大小的性能进行反应虚拟化

javascript performance ag-grid react-virtualized fin-hypergrid

9
推荐指数
2
解决办法
3172
查看次数