react-window and infinite loader scrolling issue

JKhan picture JKhan · Jun 24, 2019 · Viewed 8.2k times · Source

I have given an arbitrary number in itemCount because my list length is unknown. When I scroll down, infiniteloader loads the data normally for the first time only. But then it loads after my window view is completely blank.

Let's say my list of array contains 10 items on every fetch. How can I load data as soon as I scroll down and show content in time?

const CARD_SIZE = 265;

class CardList extends PureComponent {

    getItemData = memoize((itemsPerRow, newItems) => ({
        itemsPerRow,
        newItems
    }))


        Row = ({data, index, style }) => {
        const { itemsPerRow, newItems } = data;

        const items = [];
        const fromIndex = index * itemsPerRow;
        const toIndex = Math.min(fromIndex + itemsPerRow, newItems.length);

        for (let i = fromIndex; i < toIndex; i++) {
            items.push(
                <Card 
                key={newItems[i]}
                style={style}
                token={this.props.token}
                disableButton={this.props.disableButton} 
                image={newItems[i]} />
                );
        }
            return (
                <div style={style}>
                {items}
                </div>
            );
        }

    render() {

        const { newItems, loadMore } = this.props;

        return (
            <div style={{marginTop: "10px", height: "100vh" }}>

            <AutoSizer>
            {
                ({ height, width }) => {
                    const itemsPerRow = Math.floor(width / CARD_SIZE) || 1;
                    // const rowCount = Math.ceil(newItems.length / itemsPerRow);
                    const itemData = this.getItemData(itemsPerRow, newItems);

                    return (
              <InfiniteLoader
              isItemLoaded={index => index < newItems.length - 1}
              itemCount={5000}
              loadMoreItems={loadMore}
               >
              {({ onItemsRendered, ref }) => (

                        <List
                        height={height}
                        itemCount={5000}
                        itemData={itemData}
                        itemSize={CARD_SIZE}
                        width={width}
                        overscanCount={1}
                        onItemsRendered={onItemsRendered}
                        ref={ref}
                        >
                        { this.Row }
                        </List>

                        )}
            </InfiniteLoader>

                        )
                }
            }
            </AutoSizer> 
            </div>
            );
    }
}

Answer

lu4ezar picture lu4ezar · Mar 26, 2020

You've made a couple of mistakes here, so I'm not sure which one causes your issue.
Firstly, you don't need to return an array from Row function, just a single item:

Row = ({index, style}) => <div style={style}>{items[index]}</div>

And do not forget to pass that style prop, otherwise it won't work.

Also, pass function to itemCount, something like this one:

const itemCount = hasNextPage ? items.length + 1 : items.length;

Do not hesitate to refer to the documentation.