autoHeight with WindowScroller doesn't render full List - javascript

when i use autoHeight parameter on WindowScroller's child (List),
it doesn't render whole list of items (only few of them), but without autoHeight everything renders, but the rest of page is not scrolling.
Thank you, there is my code and screenshot:
const bars = this.props.bars
const rowRenderer = ({ index, key, style }) => {
const bar = bars.get(index)
return (
<div key={key} style={style}>
<BarListItem
key={key}
onClick={this.props.onBarClick}
{...this.props}
{...bar}
/>
</div>
)
}
return <WindowScroller>
{({ height, isScrolling, onChildScroll, scrollTop }) => (
<AutoSizer disableHeight>
{({ width }) => (
<List
autoHeight
onScroll={onChildScroll}
ref="List"
height={height}
rowCount={bars.size}
rowRenderer={rowRenderer}
rowHeight={height/5.5}
width={width}
isScrolling={isScrolling}
// onChildScroll={onChildScroll}
scrollTop={scrollTop}
/>)}
</AutoSizer>
)}
</WindowScroller>
screenshot

Related

How to make two rows inside one row react-virtualized?

I need to make for some rows react-virtualized from table, create 2 rows, 1 row it is row react-virtualized second row it is my custom row
Ho to do it, maybe has some example?
I tried use defaultTableRowRenderer() function,as far as I understand, this embeds newlines in react-virtualized table, but I not need this
its must look like this
table
My code look like this
return (
<>
<div style={{ height: "90vh" }}>
<AutoSizer>
{({ width, height }) => (
<TableVirtualized
headerHeight={70}
height={height}
overscanRowCount={5}
rowHeight={ 80}
rowCount={rowItems.length}
rowGetter={({index}) => rowItems[index]}
width={width}
className={className}
rowRenderer={rowRenderer}
>
{headerTitles.map((v:any, i:any)=>{
const key = Object.keys(v);
return (
<Column
label={v[`${key}`]}
dataKey={key}
width={200}
cellRenderer={(v: any)=> cell(v)}
key={i}
headerRenderer={()=> formatHeader(v[`${key}`])}
/>
)
}
)}
</TableVirtualized>
)}
</AutoSizer>
this my rowRender function. I think this is a bad way, because row react-virtualized height is fixed
const rowRenderer = (props: any) => {
const { index, style, className, key, rowData } = props;
if(rowData.attributes){
return (
<div className={cellProps.attributes.className}>
{defaultTableRowRenderer(props)}
<div className='blabla'>1</div>
</div>
)
}
return defaultTableRowRenderer(props);
}

React-Window with dynamic list dimensions

I'm trying to add react-window to my stack, however all examples require the width and height of the list to be statically defined like this:
import { FixedSizeList as List } from 'react-window';
const Column = ({ index, style }) => (
<div style={style}>Column {index}</div>
);
const Example = () => (
<List
height={75}
itemCount={1000}
itemSize={100}
layout="horizontal"
width={300}
>
{Column}
</List>
);
In my current code, the width and height are defined as follows:
<div
style={{
overflowY: 'scroll',
height:
width >= 600 &&
(isFirefox() ? '100%' : '-webkit-fill-available'),
width: isFirefox()
? '-moz-available'
: '-webkit-fill-available',
}}
>
{items.map(item => <MyItem ... />}
</div>
As you can see, my width and height are defined as 100% or webkit-fill-available.
How can I adapt this to make it work with react-window or react-virtualized?
I would suggest using the same logic as className in react-window, so we are going to write it like :
const Example = () => (
<List
height={75}
itemCount={1000}
itemSize={100}
layout="horizontal"
width={300}
className={isFirefox() ? 'FirefoxClass' : 'anotherStyle'}
>
{Column}
</List>
);

React Virtualized Auto Scroll Issue

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 ??
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>
)
}

React Virtualized table with CellMeasurer is not calculating the height properly

I have a strange issue going on. The react-virtualized table with CellMeasurer is not calculating the height properly.
My render function looks something like this :-
<Table
deferredMeasurementCache={this._cache}
className={mainClasses}
width={500}
height={500}
headerHeight={headerHeight}
rowHeight={this._cache.rowHeight}
rowCount={dataList.length}
sort={this.sort}
sortBy={sortBy}
sortDirection={sortDirection}
rowGetter={({ index }) => dataList[index]}
rowRenderer={this.rowRenderer}
overscanRowCount={overscanRowCount}
onRowClick={onRowClick}
>
{
columnsDef.map((item, index) => {
if (index === 0) {
return (
<Column
key={item.dataKey}
dataKey={item.dataKey}
width={25}
cellRenderer={this.checkboxCellRenderer}
disableSort={!this.isSortEnabled(item)}
headerRenderer={this.checkBoxHeaderRenderer}
/>
);
}
return (
<Column
key={item.dataKey}
dataKey={item.dataKey}
width={item.width ? item.width : 0}
label={item.label}
cellRenderer={this.dynamicCellRenderer}
disableSort={!this.isSortEnabled(item)}
headerRenderer={this.headerRenderer}
flexGrow={item.flexGrow}
/>
);
})
}
</Table>
My dynamic cell renderer function is as follows :-
dynamicCellRenderer = (data) => {
return (
<CellMeasurer
cache={this._cache}
columnIndex={0}
key={data.cellData}
parent={data.parent}
rowIndex={data.rowIndex}
>
<div
style={{
whiteSpace: 'normal'
}}
>
{data.cellData}
</div>
</CellMeasurer>
);
}
I have cache defined in constructor :-
constructor(props) {
super(props);
this._cache = new CellMeasurerCache({ minHeight: props.rowHeight, fixedWidth: true });
}
Can anyone please help me with where am I going wrong. Am I missing something with implementation of CellMeasurer? Any help is appreciated. Thanks in advance.
I had the same issue.
I think that the problem is because each cell's height is calculated before it's content is loaded.
I used the parameter measure of the CellMeasurer and call it when the content is loaded
<CellMeasurer
cache={cache}
columnIndex={0}
key={key}
parent={parent}
rowIndex={index}
width={width}
>
{({measure}) => (
<Content onLoad={measure} />
)}
</CellMeasurer>

Update list when redux store changes

I am trying to update the list when my redux store changes but for some odd reason it isn't. I have to manually refresh the page to see my changes. Here's the snippet of my List component and rowRenderer.
<InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={visibleRequest.length}
>
{({ onRowsRendered, registerChild }) => (
<AutoSizer>
{({ height, width }) => (
<List
ref={registerChild}
className="List"
height={height}
rowHeight={listRowHeight}
onRowsRendered={onRowsRendered}
rowCount={rowCount}
rowRenderer={this._rowRenderer}
width={width}
/>
)}
</AutoSizer>
)}
</InfiniteLoader>
_rowRenderer = ({ index, key, style }) => {
const { loadedRowsMap, selected } = this.state;
const row = this.getDatum(index);
let content;
if (loadedRowsMap[index] === STATUS_LOADED) {
content = row;
} else {
content = (
<div className="placeholder" style={{ width: _.random(100, 200) }} />
);
}
return (
<PendingChat
key={key}
content={content}
style={style}
row={row}
{...this.props}
/>
);
};
Yeah, I ran into the same problem. Its because the references to your objects don't change when you do
const row = this.getDatum(index);
let content;
if (loadedRowsMap[index] === STATUS_LOADED) {
content = row;
}
Take a look at immutability.

Categories