使用单元测量器虚拟化反应中的单元重叠问题

Posted

技术标签:

【中文标题】使用单元测量器虚拟化反应中的单元重叠问题【英文标题】:Cells overlapping problems in react virtualized with cell measurer 【发布时间】:2020-06-28 14:51:40 【问题描述】:

我正在使用 React Virtualized 来显示我的项目列表,它具有以下功能 1)点击任何项目,用户将被提示一个详细信息面板,他将能够更新项目的详细信息。而当他返回列表时,他将能够在列表中的项目单元格中看到详细信息。他可以添加很多细节以使其更大或通过删除细节来减小尺寸

2) 他可以删除该项目,或在列表中添加具有某些详细信息或不包含详细信息的另一个项目。

CellMeasurer 满足我的要求,因为它支持动态高度。但我有以下问题

1) 最初,当我的列表第一次安装时,前几个项目被测量并正确显示,但是一旦我滚动到最后,项目就会相互重叠。(定位不正确,我猜是 defaultHeight正在应用于未测量的单元格)。再次重新呈现列表后,这将正常工作。 2) 此外,当我更新项目的详细信息时,列表不会随着新的高度调整而更新

我确信我的实现在某个地方是不正确的,但我花了很多时间来敲定它。请让我知道在这里可以做些什么来解决这个问题

ItemView = props => 
        const index, isScrolling, key, style = props,
            items = this.getFormattedItems()[index]
        return (
            <CellMeasurer
                cache=this._cache
                columnIndex=0
                isScrolling=isScrolling
                key=key
                rowIndex=index
                parent=parent>
                (measure, registerChild) => (
                    <div key=key  style=style onLoad=measure>
                        <div
                            onLoad=measure
                            ref=registerChild
                            ...parentProps>
                            <Item
                                onLoad=measure
                                key=annotation.getId()
                                ...childProps
                            />
                        </div>
                    </div>
                )
            </CellMeasurer>
        )
    

renderDynamicListOfItems()
   return (<div>
                <List
                    height=500
                    ref=listComponent => (_this.listComponent = listComponent)
                    style=
                        width: '100%'

                    
                    onRowsRendered=()=>
                    width=1000
                    rowCount=props.items.length
                    rowHeight=this._cache.rowHeight
                    rowRenderer=memoize(this.ItemView)
                    // onScroll=onChildScroll
                    className=listClassName
                    overscanRowCount=0
                />
            </div>
     )


此外,我正在其 componentDidUpdate 中手动触发对我的项目的重新测量,如 follow()

    Component Item 
    ...
    componentDidUpdate() 
        console.log('loading called for ', this.props.annotation.getId())
        this.props.onLoad()
    
    ...

在主父项中,每次列表更新并触发 forceupdate 时,我都会重新计算列表的高度,如下所示

Component ParentList
...
    componentDidUpdate() 
        console.log("calling this parent recomputing")
        this.listComponent.recomputeRowHeights()
        this.listComponent.forceUpdateGrid()
    
...

【问题讨论】:

【参考方案1】:

我刚遇到同样的问题,结果是我的Item 组件中的一些布局更新在测量后改变了项目的高度CellMeasurer.

修复是传递measure 函数并在每次布局更新时调用它。 在我的情况下是

    图片正在加载中 以及使用Twemoji 处理的文本(将表情符号替换为图像)。

在滚动到列表顶部时添加一些新列表项后,我也无法从缓存中获取正确的高度。这可以通过向CellMeasurerCache 提供keyMapper 来解决:

    const [cache, setCache] = useState<CellMeasurerCache>();

    useEffect(() => 
        setCache(new CellMeasurerCache(
            keyMapper: (rowIndex: number, columnIndex: number) => listItems[rowIndex].id,
            defaultHeight: 100,
            fixedWidth: true,
        ));
    , [listItems]);

【讨论】:

以上是关于使用单元测量器虚拟化反应中的单元重叠问题的主要内容,如果未能解决你的问题,请参考以下文章

如何使单元格与 CollectionView 中的页脚部分重叠?

UITableView 中的自定义单元格重叠

GradientLayer 与 Swift 中的单元格标签重叠?

如何开始与表格视图中的标题重叠的单元格

UITableView 中的自定义单元格使图像在滚动时重叠

具有循环虚拟化功能的C#WPF Datagrid