KingSora / OverlayScrollbars

A javascript scrollbar plugin that hides the native scrollbars, provides custom styleable overlay scrollbars, and preserves the native functionality and feel.
https://kingsora.github.io/OverlayScrollbars
MIT License
3.78k stars 214 forks source link

component fails to initialize when using react-window #573

Closed s-ras closed 9 months ago

s-ras commented 10 months ago

I followed the instructions on how to use OverlayScrollbars alongside react-window. However I used plugins that come with react-window, particularly react-virtualized-auto-sizer and react-window-infinite-loader. Problem is, there seems to be a problem with the initialization of OS instance as the outer ref seems to be null upon rendering and once the component (in this case FixedSizeList) is rendered, even though the outer ref is no longer null, OS still doesn't initialize. I tried adding outerRef and rootRef to the list of useEffects dependencies and it still won't work.

here's the code I'm using:

    const rootRef = useRef(null);
    const outerRef = useRef(null);

    const [initialize, osInstance] = useOverlayScrollbars({
        options: {
            scrollbars: {
                theme: "os-theme-dark",
                autoHide: "move",
                dragScroll: true,
                pointers: ["mouse", "touch", "pen"],
            },
        },
    });

    useEffect(() => {
        if (rootRef.current && outerRef.current) {
            initialize({
                target: rootRef.current,
                elements: {
                    viewport: outerRef.current,
                },
            });
        }
        return () => osInstance()?.destroy();
    }, [rootRef.current, outerRef.current, osInstance, initialize]);

    //////////////////////////////////////////

    return (
            <div
                data-overlayscrollbars=""
                ref={rootRef}
                style={{
                    width: "100%",
                    height: "100%",
                }}
            >
                <AutoSizer>
                    {(size: Size) => (
                        <InfiniteLoader
                            itemCount={count}
                            loadMoreItems={loadMore}
                            isItemLoaded={isLoaded}
                        >
                            {({ onItemsRendered, ref }) => (
                                <FixedSizeList
                                    width={size.width}
                                    height={size.height}
                                    itemCount={count}
                                    itemSize={70}
                                    outerRef={outerRef}
                                    itemData={list}
                                    onItemsRendered={onItemsRendered}
                                    ref={ref}
                                >
                                    {renderRow}
                                </FixedSizeList>
                            )}
                        </InfiniteLoader>
                    )}
                </AutoSizer>
            </div>
    );
KingSora commented 10 months ago

Good day @s-ras

The problem here is probably the useEffect here, since it will run once and won't take the initialization of the AutoSizer, InfiniteLoader etc. into consideration.

Could you please create an example on CodeSandbox / StackBlitz for me? - Then I would try to create an fixed version for you.

KingSora commented 10 months ago

@s-ras I've managed to create an example with the mentioned libraries myself:

https://codesandbox.io/s/relaxed-smoke-tdpnyl?file=/index.js

I hope this solves your problem :)

KingSora commented 9 months ago

@s-ras I'll close the issue because of inactivity... In case you have any feedback regarding this please don't hesitate to post it here!