Git Product home page Git Product logo

Comments (9)

bvaughn avatar bvaughn commented on May 5, 2024 3

This feature is available in 3.1.0

from react-virtualized.

bvaughn avatar bvaughn commented on May 5, 2024

Hey dude. Thanks for taking the time to write up this proposal. Check out #25 for some previous discussion related to this. The basic approach I recommended to @oyeanuj was...

  1. Give react-virtualized a rowsCount of X + 1 (where X is the current size of your local cache).
  2. When a user scrolled near the bottom of your list you could fetch the next chunk. (To make this easier I added a new callback function, onRowsRendered, that is called each time rows are rendered and specifies the range of row indices.)
  3. If the user ever scrolls all the way to the bottom before you've loaded the next chunk of data, the last row could show a loading indicator. (This would be the responsibility of your rowRenderer function.)

This approach is responsible with the latest release of react-virtualized but does require a little bit of extra work on the user's side.

I'm not sure how I feel about moving more of this meta-logic into react-virtualized. Could be pretty cool, if people need it. Maybe it could be done in the form of a HOC of some sort?

Edit Just realized that the last step of the above proposal (rendering a loading indicator as the last row) only works for VirtualScroll. It would not work for FlexTable since row-rendering is managed by the tables and is based on columns. Hmm. That may poke a pretty big hole in that approach.

from react-virtualized.

olslash avatar olslash commented on May 5, 2024

I've been working on implementing this --

  1. From my API I know how many results will ultimately exist, I set the rowsCount to that number (say 1000, even though i only have 100 loaded)
  2. Set my row renderers to show a loading message instead of row content if data is null.
  3. If i get within ~30 rows of the end of my actual data, I fire a redux action to load more rows.
  4. I set a marker at (end of actual data + number of new rows loaded) so I a) don't try to load the same data multiple times and b) can load even more data if the user scrolls past my first load of extra rows before loading is done.

One problem I'm running into is that onRowsRendered is being called from render() itself, so i can't setState() from it without a setTimeout() (to set the marker). Obviously I can do this with an instance property instead of state, but in any case I think it makes more sense to have that callback be fired from componentDidUpdate as render() is supposed to be free of side-effects.

from react-virtualized.

bvaughn avatar bvaughn commented on May 5, 2024

Thanks for sharing your approach, @olslash. I think the suggestion of moving onRowsRendered to componentDidUpdate sounds like a reasonable one. I've created #40 for that.

from react-virtualized.

oyeanuj avatar oyeanuj commented on May 5, 2024

Back to this library and discussion after a break. Great discussion happening, and wanted to add another perspective on the approaches being discussed.

From @bvaughn

Give react-virtualized a rowsCount of X + 1 (where X is the current size of your local cache).
When a user scrolled near the bottom of your list you could fetch the next chunk. (To make this easier I added a new callback function, onRowsRendered, that is called each time rows are rendered and specifies the range of row indices.)

From @olslash

  1. Set my row renderers to show a loading message instead of row content if data is null.

To make it work for both infinite scroll use-case and load-more use-case, an approach could be to combine the above approaches. At the risk of adding more to the library, the component can fire a load more callback (passed to the component) when user reaches a threshold point (passed to the component) and until data is loaded, show a load function/valid JSX (also passed to the component).

A couple of libraries out there are doing adopting variations of that approach, in case it helps us see what to do or not to do.

https://github.com/nrako/react-component-scrollload
https://github.com/seatgeek/react-infinite

from react-virtualized.

bvaughn avatar bvaughn commented on May 5, 2024

FYI @olslash, your suggestion has been implemented via issue #40 and is available in release 2.7.0.

from react-virtualized.

olslash avatar olslash commented on May 5, 2024

nice, thank you!

from react-virtualized.

bvaughn avatar bvaughn commented on May 5, 2024

No problem. :)

Thanks for contributing to the discussion, @oyeanuj.

To make it work for both infinite scroll use-case and load-more use-case, an approach could be to combine the above approaches. At the risk of adding more to the library, the component can fire a load more callback (passed to the component) when user reaches a threshold point (passed to the component) and until data is loaded, show a load function/valid JSX (also passed to the component).

One of the unique things about react-virtualized that isn't in react-infinite- (actually it's the primary reason I created react-virtualized in the first place)- is that props can be used to jump to a row automatically. This actually throws a bit of a wrench into the idea of setting a simple threshold that can be used to load more. Thinking of @olslash use case- a user could view rows 0..10 and then skip directly to 500..510 without viewing 11..499. In that event, the rows in the middle don't actually need to be loaded. It seems like the threshold approach used by react-component-scroll or the infiniteLoadBeginEdgeOffset approach in react-infinite would result in all rows between 0..510 being loaded. Maybe I'm nitpicking by worrying about that kind of optimization? But I do like the idea of leaving it open to the developer to decide how much they want to optimize their loading.

I'm also reluctant to complicate the virtualization components with things that are meta to rendering. Maybe an elegant solution would be for me to release a high-order component that could be used to decorate a list or table with this behavior? Any thoughts on that? Pulling this out of my ass a bit, but maybe something that looked like...

<InfiniteListLoader
  isRowLoaded={rowIndex => true}
  loadMoreRows={({ startIndex, stopIndex }) => {}}
  threshold={10}
>
  <VirtualScroll ... />
</InfiniteListLoader>
Property
isRowLoaded Function that informs whether a specified row has been loaded
loadMoreRows Function responsible for loading a chunk of data at least as great as the specified start/stop index
threshold How far in advance to start prefetching data

I like the idea of this approach because it doesn't complicate the existing components any and it leaves users free to implement their own loading solution if they want to optimize it in their own way.

Thoughts?

from react-virtualized.

bvaughn avatar bvaughn commented on May 5, 2024

FYI for anyone interested, I've got PR #51 up with the new InfiniteLoader component. Need to write a few more tests and stuff but I think it's nearly ready for release. Feel free to weigh-in on the API if you'd like (although preferably before a release has been made) ;)

from react-virtualized.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.