bvaughn / react-window

React components for efficiently rendering large lists and tabular data
https://react-window.now.sh/
MIT License
15.91k stars 787 forks source link

Use InfiniteLoader + AutoSizer + FixedSizeGrid all together #609

Closed justinasfour04 closed 2 months ago

justinasfour04 commented 2 years ago

I'm trying to do the following but nothing seems to render and I can't figure out why

return (
    <InfiniteLoader
      ref={listRef}
      isItemLoaded={isItemLoaded}
      itemCount={itemCount}
      loadMoreItems={loadMoreItems}
    >
      {
        ({ ref, onItemsRendered }) => (
          <AutoSizer>
            {
              ({ height, width }) => (
                <Grid
                  ref={ref}
                  className="Grid"
                  columnCount={Math.floor(width / 200)}
                  columnWidth={200}
                  height={height}
                  width={width}
                  rowCount={rowCount}
                  rowHeight={200}
                  onItemsRendered={itemRenderer(onItemsRendered)}
                >
                  {
                    ({ columnIndex, rowIndex, style }) => (
                      <Cell
                        columnIndex={columnIndex}
                        rowIndex={rowIndex}
                        style={style}
                        columnCount={columnCount}
                        items={items}
                        isItemLoaded={isItemLoaded}
                      />
                    )
                  }
                </Grid>
              )
            }
          </AutoSizer>
        )
      }
    </InfiniteLoader>
  );

Can these three elements be used together?

xh3b4sd commented 2 years ago

Hey, I think I ran into the same problem you did. I figured you have to render within the dom directly. Returning the component doesn't work for some reason. I don't know anything about react so I just fiddled a bit until it worked. The items appear to be loaded and removed when scrolling. Somebody please give feedback if this approach is wrong or could be improved by any means. Hope the snipped below helps.

const Cell = ({ columnIndex, rowIndex, style }) => (
  < div style={style} >
    // cour content here
  </div >
);

const Example = () => (
  <AutoSizer>
    {({ height, width }) => (
      <InfiniteLoader
        isItemLoaded={isItemLoaded}
        itemCount={1000}
        loadMoreItems={loadMoreItems}
      >
        {({ onItemsRendered, ref }) => (
          <Grid
            className="Grid"
            columnCount={3}
            columnWidth={width / 3}
            height={height}
            onItemsRendered={onItemsRendered}
            ref={ref}
            rowCount={60}
            rowHeight={width / 3}
            width={width}
          >
            {Cell}
          </Grid>
        )}
      </InfiniteLoader>
    )}
  </AutoSizer>
);

render(<Example />, document.getElementById("root"));

Update: The snipped above is from my index.js within a brand new react app. I threw away the App.js because I tried to work in there, which is the problem OP apparently has as well.

justinasfour04 commented 2 years ago

I figured out what the issue was, I need to put all that in a div with height and width. It wasn't rendering anything because height was 0px

umagon commented 12 months ago

I'm trying to do the following but nothing seems to render and I can't figure out why

return (
    <InfiniteLoader
      ref={listRef}
      isItemLoaded={isItemLoaded}
      itemCount={itemCount}
      loadMoreItems={loadMoreItems}
    >
      {
        ({ ref, onItemsRendered }) => (
          <AutoSizer>
            {
              ({ height, width }) => (
                <Grid
                  ref={ref}
                  className="Grid"
                  columnCount={Math.floor(width / 200)}
                  columnWidth={200}
                  height={height}
                  width={width}
                  rowCount={rowCount}
                  rowHeight={200}
                  onItemsRendered={itemRenderer(onItemsRendered)}
                >
                  {
                    ({ columnIndex, rowIndex, style }) => (
                      <Cell
                        columnIndex={columnIndex}
                        rowIndex={rowIndex}
                        style={style}
                        columnCount={columnCount}
                        items={items}
                        isItemLoaded={isItemLoaded}
                      />
                    )
                  }
                </Grid>
              )
            }
          </AutoSizer>
        )
      }
    </InfiniteLoader>
  );

Can these three elements be used together?

Mine is not calling loadMoreItems. It complaints about onItemsRendered type not being compatible with GridOnItemsRendered. The one that comes from InfiniteLoader is of type ListOnItemsRendered. What's that itemRenderer function you've got there?