Reputation: 1358
I am using react-virtualized v-9.21.2 to display a list, I am having an issue on insertion of a new item, upon inserting a new item to the list I am clearing the cache and updating the listkey to auto resize the height, otherwise, the new added item will be cropped but when the listkey get updated the list automatically scroll to top and this is not a desired behavior, my code is as follow:
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>
)
}
I tried programmatically to scroll to adjust the height without the update of the key, it worked but still not accurate, So, How can I update the virtualized with a new item and adjust the height without scrolling ??
Upvotes: 4
Views: 3869
Reputation: 99
If your data has a unique key, I think you can create a ListItem
component add an useEffect
hook calling the measure
function when the data change. This may have performance impact.
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>
)
}
Upvotes: 2