bvaughn / react-window

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

Is it possible to dynamically update the itemSize height in VariableSizeList? #729

Closed gonta1026 closed 1 year ago

gonta1026 commented 1 year ago

issue

I would like to use handleChangeHeight to change the height of the itemSize in the VariableSizeList. However, when I update the height of the items, the height of the target row in the VariableSizeList is not updated. I think this is because the itemSize is updated only for the initial rendering.


    const [items, setItems] = useState<CustomItem[]>([]);

    const handleChangeHeight = (itemIndex: number) => {
        const copyItems = [...items];
        if (copyItems[itemIndex].height === 200) {
            copyItems[itemIndex].height = 70;
        } else {
            copyItems[itemIndex].height = 200;
        }
        setItems(copyItems);
    };

    return (
        items.length > 0 && (
            <Box background='#fff' mt='20px'>
                <VariableSizeList
                    height={500}
                    itemCount={items.length}
                    itemSize={(index) => items[index].height} // example default height is 80。Updates to 200 are not reflected.
                    width={Infinity}
                >
                    {({ index, style }) => {
                        const item = items[index];
                        return (
                            <div
                                {...{ style }}
                                // style={{ height: item.height }} // Overwriting is buggy.
                                onClick={() => handleChangeHeight(index)} 
                            >
                                row {index}
                            </div>
                        );
                    }}
                </VariableSizeList>
            </Box>
        )
    );
timminata commented 1 year ago

I am experiencing a similar issue. I also feel like the provided .forceUpdate method is not doing anything. I made a code sandbox here and have not been able to get the variable height to work at all yet: https://codesandbox.io/s/proud-leaf-9c38ch?file=/index.js

Let me know if you've managed to solve this issue!

gonta1026 commented 1 year ago

@timminata Thank you! The following comment solved my issue by calling resetAfterIndex(0) in handleChangeHeight!

    const handleChangeHeight = (itemIndex: number) => {
        listRef.current?.resetAfterIndex(0); // clear cache
        const copyItems = [...items];
        if (copyItems[itemIndex].height === 200) {
            copyItems[itemIndex].height = 70;
        } else {
            copyItems[itemIndex].height = 200;
        }
        setItems(copyItems);
    };

https://github.com/bvaughn/react-window/issues/731#issuecomment-1642251004

gonta1026 commented 1 year ago

My issue has been resolved and is closed.

timminata commented 1 year ago

@timminata Thank you! The following comment solved my issue by calling resetAfterIndex(0) in handleChangeHeight!

    const handleChangeHeight = (itemIndex: number) => {
        listRef.current?.resetAfterIndex(0); // clear cache
        const copyItems = [...items];
        if (copyItems[itemIndex].height === 200) {
            copyItems[itemIndex].height = 70;
        } else {
            copyItems[itemIndex].height = 200;
        }
        setItems(copyItems);
    };

#731 (comment)

Pleasure! Glad it helped - I'll leave my issue open for a bit in case @bvaughn can shed some light on the difference between .forceUpdate() and .resetAfterIndex(index). I'm also glad my issue is solved now 🎉