使用动态高度列表时重叠元素

时间:2017-07-27 02:13:01

标签: javascript react-virtualized

我遇到的问题几乎与Facebook在呈现它时的问题相同。一旦发布了很多帖子,就会出现性能问题。经过一些研究后,我发现反应虚拟化,这很棒,但我很难让它适用于我的应用程序。

这些是我面临的问题:

  1. 由于每个帖子都可以嵌入iframe或图片,因此我会在加载这些项目后从measure触发CellMeasurer回调。因此,有些项目似乎未对齐。我每次调用parent.measureAllRows()回调时都尝试parent.recomputeRowHeights()measure,看它是否会修复它,但它没有。
  2. 每个帖子都有一个可展开的部分,因此我需要重新计算它的高度。除了将道具发送到组件之外还有其他选择吗?
  3. 这是设置:

    class VirtualPostList extends React.PureComponent {
      constructor(props, context) {
        super(props, context);
        this._cache = new ReactVirtualized.CellMeasurerCache({
          fixedWidth: true,
          defaultHeight: 400
        });
        this.rowRenderer = this.rowRenderer.bind(this);
      }
    
    
      rowRenderer({index, isScrolling, key, parent, style}) {
        return (
          <ReactVirtualized.CellMeasurer
            cache={this._cache}
            columnIndex={0}
            key={key}
            parent={parent}
            rowIndex={index}>
            {({measure}) => (
              <div key={key} style={style}>
                <Post onLoad={measure}/>
              </div>
            )}
          </ReactVirtualized.CellMeasurer>
        )
      }
    
      componentDidUpdate(){
        this.listComponent.recomputeRowHeights();
      }
    
      render() {
        const cache = this._cache;
        const rowCount = this.props.posts.length;
        const _this = this;
        return (
          <ReactVirtualized.WindowScroller>
            {({height, isScrolling, onChildScroll, scrollTop}) =>
              <ReactVirtualized.AutoSizer disableHeight>
                {({width}) =>
                  <ReactVirtualized.List
                    autoHeight
                    isScrolling={isScrolling}
                    height={height}
                    width={width}
                    rowCount={rowCount}
                    deferredMeasurementCache={cache}
                    rowHeight={cache.rowHeight}
                    rowRenderer={this.rowRenderer}
                    scrollTop={scrollTop}
                    onScroll={onChildScroll}
                    ref={(listComponent) => _this.listComponent = listComponent}
                  />
                }
              </ReactVirtualized.AutoSizer>}
          </ReactVirtualized.WindowScroller>
        )
      }
    }
    

    重叠示例:

    enter image description here

1 个答案:

答案 0 :(得分:0)

正如@brianvaughn建议的那样,我并没有在每个地方都使用measure方法。由于元素不仅具有图像,而且可以自我扩展或收缩,因此它们变得有点模糊,难以保留。

由于我想避免手动调用measure,我将ResizeObserver附加到组件,就像ReactMeasure一样。之后,我将rowRenderer函数更改为:

  rowRenderer({index, isScrolling, key, parent, style}) {
    return (
      <ReactVirtualized.CellMeasurer
        cache={this._cache}
        columnIndex={0}
        key={key}
        parent={parent}
        rowIndex={index}>
        {({measure}) => (
          <div key={key} style={style}>
            <ResizeObservable onResize={measure}>
              <Post/>
            </ResizeObservable>
          </div>
        )}
      </ReactVirtualized.CellMeasurer>
    )
  }

如您所见,每次调整大小时都会调用measure函数。这还包括何时加载图像或iframe,因此无需手动调用它们