bvaughn / react-virtualized-auto-sizer

Standalone version of the AutoSizer component from react-virtualized

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Access the component height from outside the component to pass to itemSize

rchancey opened this issue · comments

Hi ya @bvaughn ,
I am using the react-window and the react-virtualized auto sizer.. and I have a virtual book that I display and each paragraph is a component.

the paragraphs are variable heights.. of course that changes based on the width of the page etc etc.

using the ref I can get the height and set that within the function.. or even use react -use-measure... but the challenge exposing that height outside the component to use that to get set the height in the auto-sizer itemSize

Any ideas on how to export a components height outside the component so I can pass it to the autosized? Hope this makes sense.

might even be interesting to make this a built in thing that the auto0sizer can work with flex components

This sounds like a question about react-window, rather than a question about this library. The AutoSizer component passes the dimensions of the outer container (the thing your list is rendered into). The variable size of an item in the list is managed by the list itself (react-window)

If you want variable height support, I might suggest you check out react-virtualized as it has built-in support for this.

Tried it.. hit the same issue as others. renders the first set of elements and stops. Also it still wants a row height.

I can't figure out how to give any of the react-window or react-virtualized a list that has random heights and not have to set a row height..thats the piece thats missing. Is there a simple example of that we can look at? its a GREAT library and it renders my 500k list easily. . just need the final piece not to have to pass a row height @bvaughn ?

It seems others have done what I ended up doing and using a ref to get the rendered height of the list row and use that in the getrowHeight: bvaughn/react-window#582

I thought there was a way to automate that somehow.. @bvaughn great library btw.. we owe you a coffee for sure man !

I can't figure out how to give any of the react-window or react-virtualized a list that has random heights

That's what the CellMeasurer component is intended to be used for (see the docs) but it sounds like you got it figured out.

@bvaughn great library btw.. we owe you a coffee for sure man !

Thank you! he he he givebrian.coffee

P.S. Thanks so much for your generosity 🙇🏼

Hey @bvaughn ...well that code did not work since React 18 does not like it. The height is zero.

I will look at the CellMeasurer might have the right idea.. set a default value and then adjust as it render... I noticed in the examples there was some flickering and line redraws.. so .. not sure. React 18 does not like rendering invisible somehow.. it did not generate a height. .. I will update. you but if you have any other ideas.. would be greatly appreciated.

this is a very common use case it seems.... just have to get the right combination! :)

@bvaughn most welcome... you have done a great job.. and actually I am combining your libraries, with react highlight (also your library) and lunr .. sort of interesting :)

@bvaughn do you do contract work? Are you interested if you are not yet?

Thank you! I really appreciate OSS interactions like this one. :)

Dynamic height is a tough use case to get right. That's why I didn't really try to support it with react-window.

I don't know if this would even be remotely useful to you, but I remember putting together a really minimal example project a few years ago that was just vanilla JS (no React) that showed how you could do a dynamically sized virtual list:
https://github.com/bvaughn/infinite-list-reflow-examples

@bvaughn do you do contract work? Are you interested if you are not yet?

I haven't done contract work in a long time. I probably don't have the bandwidth for it, unless it would be a very small project.

@bvaughn What's the right way to contact you outside this git so I can share our project to see if you are interested. It would be very small for your skills but still challenging enough to make it interesting. Very simple use case. We are using 3... in fact I think 4 of your libraries :) . I did not realize they were all yours until last night on a call with someone. haha.

That's a funny coincidence :)

Email is the best way to contact me. brian.david.vaughn@gmail.com

@bvaughn I did follow one of the examples .. but there are no scroll bars.. but it is doing a decent job rendering..

here is the code in case others are looking for this same thing.
but why no scroll bars? in fact the scrolling is a little jerky.

// Mo// Modules
import React, { useEffect, useRef } from "react";
// Components
import { VariableSizeList as List } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";
// Styles
import styles from "./Regulations.css";

const RegulationList = ({ documents }) => {
    // References
    const listRef = useRef({});
    const rowHeights = useRef({});

    function getRowHeight(index) {
        return rowHeights.current[index] || 40;
    }

    function Row({ index, style }) {
        const rowRef = useRef({});

        useEffect(() => {
            if (rowRef.current) {
                setRowHeight(index, rowRef.current.clientHeight);
            }
            // eslint-disable-next-line
        }, [rowRef]);

        return (
            <div style={style}>
                <div ref={rowRef} style={styles.documentContainer}>
                    {documents[index]}
                </div>
            </div>
        );
    }

    function setRowHeight(index, size) {
        listRef.current.resetAfterIndex(0);
        rowHeights.current = { ...rowHeights.current, [index]: size };
    }

    return (
        <AutoSizer style={styles.listContainer}>
            {({ height, width }) => (
                <List
                    className="List"
                    height={height}
                    itemCount={documents.length}
                    itemSize={getRowHeight}
                    ref={listRef}
                    width={width}
                >
                    {Row}
                </List>
            )}
        </AutoSizer>
    );
};

export default RegulationList;



const styles = {
    listContainer: {
      height: "700px",
      width: "100%"
    },
    documentContainer: {
      display: "flex",
      flex: "0 0 auto",
      justifyContent: "flex-start",
      width: "100%"
    }
  };
  
  export default styles;

Edited for formatting by @bvaughn

This looks wrong:

function setRowHeight(index, size) {
  listRef.current.resetAfterIndex(0);
  rowHeights.current = { ...rowHeights.current, [index]: size };
}

Try:

function setRowHeight(index, size) {
  rowHeights.current = { ...rowHeights.current, [index]: size };
  listRef.current.resetAfterIndex(index);
}

That being said, this thread has gone pretty far off track for this repo, so it's probably best to wind it down. :)