我正在使用React Virtualized来打开我的项目列表,该列表具有以下功能1( on单击任何项目,用户都会收到一个详细信息面板的提示,用户可以在其中更新项目的详细信息。当他回到列表时,他将能够在列表中的项目单元格中看到详细信息。他可以添加很多细节,使其更大或通过删除细节来缩小尺寸
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>
)
}
此外,我正在手动触发我的项目在其组件DidUpdate中的重新测量,如下所示((
Component Item
...
componentDidUpdate() {
console.log('loading called for ', this.props.annotation.getId())
this.props.onLoad()
}
...
在主父级中,每次列表更新时,我都会重新计算列表的高度,并触发如下所示的强制更新
Component ParentList
...
componentDidUpdate() {
console.log("calling this parent recomputing")
this.listComponent.recomputeRowHeights()
this.listComponent.forceUpdateGrid()
}
...
我刚刚遇到了同样的问题,结果是Item
组件中的一些布局更新在CellMeasurer
测量项目后更改了项目的高度。
修复方法是向下传递measure
函数,并在每次布局更新时调用它。就我而言,是
- 正在加载的图像
- 以及用CCD_ 4(用图像代替表情符号(操纵的文本
在滚动到列表顶部时,在准备了一些新的列表项后,我也遇到了从缓存中获取正确高度的问题。这可以通过向CellMeasurerCache
:提供keyMapper
来解决
const [cache, setCache] = useState<CellMeasurerCache>();
useEffect(() => {
setCache(new CellMeasurerCache({
keyMapper: (rowIndex: number, columnIndex: number) => listItems[rowIndex].id,
defaultHeight: 100,
fixedWidth: true,
}));
}, [listItems]);