首页 > 解决方案 > React 虚拟化自动滚动问题

问题描述

我正在使用 react-virtualized v-9.21.2 显示列表,我在插入新项目时遇到问题,在将新项目插入列表时我正在清除缓存并更新 listkey 以自动调整高度,否则,新添加的项目将被裁剪,但是当 listkey 更新时,列表会自动滚动到顶部,这不是所需的行为,我的代码如下:

 UNSAFE_componentWillReceiveProps(nextprops) {
    if (this.props.items.length !== nexprops.items.lenght)) {
    // clear the cache and update the listKey
    this.cache.clearAll();
    this.virtualizedList && this.virtualizedList.recomputeRowHeights();
    this.listKey += 1
 }


renderItem = ({ index, key, parent, style }) => {
        return (
            <CellMeasurer
                cache={this.cache}
                columnIndex={0}
                key={`CellMeasurerRow_${key}`}
                parent={parent}
                rowIndex={index} >
                <div
                    key={`Item__${key}`}
                    style={style}
                    className='row'>
                    <Item
                        style={style}
                        key={`Item_${index}`}
                    />
                </div>
            </CellMeasurer>
        )
    }



render(){
    return (
        <WindowScroller
            key={`Scroller_${this.listKey}`}
            ref={(e) => this.windowRef = e} >
            {({ height, isScrolling, onChildScroll, registerChild, scrollTop, }) => (
                <AutoSizer>
                    {({ width }) => (
                        <React.Fragment key={registerChild}>
                            <List
                                ref={`ListKey_${this.listKey}`}
                                autoHeight
                                isScrolling={isScrolling}
                                onScroll={onChildScroll}
                                key={this.listKey}
                                scrollTop={scrollTop}
                                height={height}
                                rowCount={this.props.items.length}
                                rowRenderer={this.renderItem}
                                deferredMeasurementCache={this.cache}
                                rowHeight={this.cache.rowHeight}
                                width={width}
                                overscanRowCount={10} />
                     

                        </React.Fragment>
                    )}
                </AutoSizer>
            )}
        </WindowScroller>
    )
}

我尝试以编程方式滚动以调整高度而不更新键,它有效但仍然不准确,那么,如何使用新项目更新虚拟化并调整高度而不滚动?

标签: javascriptreactjsscrollreact-virtualized

解决方案


如果您的数据具有唯一键,我认为您可以创建一个ListItem组件,在数据更改时添加一个useEffect调用该函数的钩子。measure这可能会对性能产生影响。

function ListItem(props) {
  useEffect(props.measure, [props.data.id]);
  return (
    <div style={props.style}>
      {/* content render */}
    </div>
  );
}
renderItem = ({ index, key, parent, style }) => {
        const item = getItem(index); // suppose item data structure: { id: unique_key }
        return (
            <CellMeasurer
                cache={this.cache}
                columnIndex={0}
                key={`CellMeasurerRow_${key}`}
                parent={parent}
                rowIndex={index} 
            >
               {(measure) => (
                  <ListItem 
                    key={`Item__${key}`} style={style} 
                    data={item}
                    measure={measure}
                  />
               )}
            </CellMeasurer>
        )
    }

推荐阅读