Reputation: 119
I need to render long list via react-window library. I can't be sure that all rows will be the same size so it forces me to use VariableSizeList. So is there a way to calculate row height when you know only index of row and actual data to be rendered?
I think it's possible to render it somehow not visible to the end user and get height from but I'm not sure is it the right way.
Upvotes: 2
Views: 3998
Reputation: 38671
I am facing the same issue, you can use the itemSize
to specify the item height. For me I specify the size like this:
<VariableSizeList
ref={virtualListRef}
width={width}
height={height}
estimatedItemSize={500}
initialScrollOffset={getInitialScrollOffset()}
itemCount={pdf.numPages}
overscanCount={0}
onScroll={(e: ListOnScrollProps) => handleWindowPdfScroll(e)}
itemSize={(rowIndex) => getPageHeight(rowIndex, width)}
>
</VariableSizeList>
and this is the getPageHeight
function:
const getPageHeight = (rowIndex: number, width: number) => {
if (!pageViewports) {
throw new Error("getPageHeight() called too early");
}
const pageViewport = pageViewports[rowIndex];
const scale = width / pageViewport.width;
const actualHeight = pageViewport.height * scale * projAttribute.pdfScale;
return actualHeight + 10;
};
Upvotes: 0
Reputation: 6709
Yes when using VariableSizeList
specify an itemSize
function.
eg
itemSize = {(i) => onGetItemSize(rows[i])}
The onGetItemSize measures the content by:
For example:
onGetItemSize={((row) =>
{
let text = row.original.text;
// if no text, or text is short, don't bother measuring.
if (!text || text.length < 15)
return rowHeight;
// attempt to measure height by writting text to a, kind of hidden element.
let hiddenElement = document.getElementById(this.hiddenFieldName());
if (hiddenElement)
{
hiddenElement.textContent = text;
let ret = hiddenElement.offsetHeight;
hiddenElement.textContent = '';
if (ret > 0)
return Math.max(ret, rowHeight);
}
// fallback
return rowHeight;
})}
Then include this empty element at an appropriate place in the DOM.
<div id={this.hiddenFieldName()} style={{ visibility: 'visible', whiteSpace: 'normal' }} />
Upvotes: 1