I'm using the CellMeasurer in order to calculate a VirtualScroll' row's height, and it's using a completely wrong measurement for the initial batch of visible rows.
This ends up something like the following (the top 4 rows were a part of the initial batch, and have a very tall height):

The virtualized components that I'm using are as follows:
<WindowScroller>
{ ({ height, scrollTop }) =>
<AutoSizer disableHeight>
{ ({ width }) =>
<CellMeasurer
cellRenderer={ cell => this.renderVirtualRow(cell.rowIndex) }
columnCount={ 1 }
rowCount={ items.length }
width={ width } >
{ ({ getRowHeight }) =>
<VirtualScroll
autoHeight
style={ { background: '#EEE' } }
width={ width }
height={ height }
scrollTop={ scrollTop }
rowCount={ items.length }
rowHeight={ getRowHeight }
rowRenderer={ row => this.renderVirtualRow(row.index) } />
}
</CellMeasurer>
}
</AutoSizer>
}
</WindowScroller>
If I scroll, the rows that get rendered all have the correct heights, but the initial batched rows are still all wrong.
It's happening on both Chrome and FireFox.
Ah, interesting. My guess is that the initial width value is smaller (maybe due to the parent DOM or CSS styles or however your page is constructed). That probably causes the text to wrap a lot which makes the columns taller.
Once CellMeasurer has measured a cell- the measurements are cached for performance purposes. (This avoids us having to re-render the cell content many times.) CellMeasurer provides methods for you to invalidate the cached values though- in this case, the resetMeasurementForRow param passed to the child function.
VirtualScroll also caches measurements (to avoid unnecessary overhead of calling rowHeight getter functions).
So basically you'll need to let both VirtualScroll and CellMeasurer know if the heights may be invalid due to a resized width. I'd suggest trying this:
ref to VirtualScrollresetMeasurementForRow param passed to the child function.AutoSizer for the onResize event.resetMeasurementForRow function whenever AutoSizer resizes. (You can skip calling if only the height has changed.)recomputeRowHeights method of VirtualScroll as well to let it know that heights need to be remeasured. This will cause it to ask CellMeasurer to remeasure the visible heights.So basically something like this:
<AutoSizer
disableHeight
onResize={({ width }) => {
// Heights may be invalid if width has changed...
if (width !== this._mostRecentWidth) {
this._resetMeasurementForRow && this._resetMeasurementForRow()
this._virtualScroll && this._virtualScroll.recomputeRowHeights()
}
}}
>
{({ width }) => {
this._mostRecentWidth = width
return (
<CellMeasurer {...otherCellMeasurerProps}>
{({ getRowHeight, resetMeasurementForRow }) => {
this._resetMeasurementForRow = resetMeasurementForRow
return (
<VirtualScroll
ref={(ref) => this._virtualScroll = ref}
{...otherVirtualScrollProps}
/>
)
}}
</CellMeasurer>
)
}}
</AutoSizer>
Disclaimer: I have not tried this. I have never actually used CellMeasurer in a production app. (I wrote it because I thought it would be useful to others- but I haven't yet had a use for it myself.)
Unfortunately, that didn't have any effect.
Got a Plunker you can share with me that reproduces this?
Ping for more information. :)
Closing for now. Don't have enough info to help diagnose this further.
Comments will still notify me via email- so if you get a chance to provide a Plunker or some way to reproduce, let me know and I'll be happy to take another look. :)
Hi @bvaughn
FWIW I encountered the same issue, in a Next.js SSR app. I think your diagnostic is correct, but I couldn't figure out how to improve the measurement as everything in my design is fluid, and inside a swipe-view to make it even more complicated.
My solution was as follows:
componentDidMount() {
if (this.list) {
setTimeout(() => {
cache.clearAll();
this.list.recomputeRowHeights();
}, 0);
}
}
Most helpful comment
Hi @bvaughn
FWIW I encountered the same issue, in a Next.js SSR app. I think your diagnostic is correct, but I couldn't figure out how to improve the measurement as everything in my design is fluid, and inside a swipe-view to make it even more complicated.
My solution was as follows: