Comments (9)
This feature is available in 3.1.0
from react-virtualized.
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...
- 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.) - 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.
I've been working on implementing this --
- 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)
- Set my row renderers to show a loading message instead of row content if data is null.
- If i get within ~30 rows of the end of my actual data, I fire a redux action to load more rows.
- 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.
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.
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
- 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.
FYI @olslash, your suggestion has been implemented via issue #40 and is available in release 2.7.0
.
from react-virtualized.
nice, thank you!
from react-virtualized.
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.
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)
- Confused about zooming with virtualization HOT 1
- Accessibility issues in Table, Column components HOT 2
- Is this Project Dead or Unmaintained? Which are the alternatives? HOT 2
- How using checkbox in react-virtualized?
- Grid rows disappear when sibling elements are conditionally rendered in HOT 1
- [Question] What are the criteria for determining the number of rows in a list?
- Your official website is blocked HOT 1
- Main link is broken HOT 1
- Access to Multigrid public method recomputeGridSize() returns undefined
- Version 9.22.5 is a ghost not visible in this repository?
- Height Issue after rendering
- Virtualisation fail ? Why invisible content is added to my list ?
- react18.2.0 HOT 1
- Tips for displaying a dropdown to overflow the React Virtualized container without being hidden?
- Failed to fetch dynamically
- The styles.css isn't part of the 9.23.0 version
- How to load JSON-formatted data virtually?
- TypeError : RegisterChild in WindowScroller
- Props ScrollElement of WindowScroller load every items if parent is InfiniteLoader HOT 2
- Autosizer component does not accept any refs or spread props.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-virtualized.