Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[react-window-infinite-loader] Can't call resetAfterIndex() on child VariableSizeList, because of ref; #417

Closed
RosenTomov opened this issue Feb 9, 2020 · 2 comments

Comments

@RosenTomov
Copy link

Hello, is there a way to call resetAfterIndex() on a child VariableSizeList, inside InfiniteLoader?

The ref that comes from InfiniteLoader is a function:

function _setRef() {
  length: 1
  ​name: ""
  ​prototype: Object { … }
  ​<prototype>: function ()

My current "solution" is to use my own ref, instead of the one from InfiniteLoader

<InfiniteLoader isItemLoaded={isItemLoaded} itemCount={1000} loadMoreItems={loadMoreItems}>
    {({ onItemsRendered }) => {
      return <VariableSizeListWrapper onItemsRendered={onItemsRendered} />;
    }}
</InfiniteLoader>

and inside the VariableSizeListWrapper

const ref = React.useRef();
...
React.useEffect(() => {
    if (ref?.current) {
      ref.current.resetAfterIndex(0);
    }
  }, [someCollection]);
...
<VariableSizeList ref={ref} ...
....

Everything seems to be working - loading more elements, itemSize is updated, when items are added or re-ordered, etc, but I get this warning: Invalid list ref; please refer to InfiniteLoader documentation.

Looking at dist/index.esm.js, it might be messing up with "_loadUnloadedRanges", but I haven't noticed anything.

@bvaughn
Copy link
Owner

bvaughn commented Feb 9, 2020

The solution here is to use a "callback ref" to get a handle on the VariableSizeList ref, then pass that on to InfiniteLoader too.

const yourRef = useRef(null);

<InfiniteLoader {...props}>
  {({ onItemsRendered, ref }) => (
    <List
      ref={list => {
        // Pass List ref through to InfiniteLoader
        ref(list);

        // And store a copy for yourself.
        yourRef.current = list;
      }}
      {...props}
    />
  )}
</InfiniteLoader>;

@waleedshkt
Copy link

Had the same issue. @bvaughn, thank you for the solution.

React-window is a great small performant lib. It works very well. But in a case requiring lazy loading of images (actual dispatching of the GET request when each item comes into view), this window-scrolling isn't efficient at all. Few issues that emerge definitely when scrolling fast, or back up and down again:

  • GET requests get triggered for each image even if previously fetched. Thus, putting a hefty load computationally and at the backend. If not using CDN, good luck with the huge bill waiting!
  • Data leakage during unmounting of item moved out of view. This is due to ajax/ async operation happening in useEffect/ componentDidMount and not finishing when item gets unmounted on rapid scrolling. Hence, a need for complex logic to take care of this
  • If using a state to capture already fetched images, a problem arises when setting state is async and doesn't put images in FIFO order.

Therefore, I'd love to have the software legends here add a feature to nicely combine image lazy-loading with react-window :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants