I can't find any code example or docs that answers this:
- Achieve almost complete infinite scroll -> unknown # of items, but there is a finite amount that may be infeasible to compute beforehand - e.g. at some point the list needs to stop scrolling
- Can I trigger first load of data from within InfiniteScroller/List - it seems you need to pass in a data source that is populated with initial page
I am using this example: https://github.com/bvaughn/react-virtualized/blob/master/docs/creatingAnInfiniteLoadingList.md
along with CellMeasurer for dynamic height: https://github.com/bvaughn/react-virtualized/blob/master/source/CellMeasurer/CellMeasurer.DynamicHeightList.example.js
The docs for InfiniteLoader.rowCount say: "Number of rows in list; can be arbitrary high number if actual number is unknown."
So how do you indicate there are no more rows.
If anyone can post an example using setTimeout() to simulate dynamic loaded data, thanks. I can likely get CellMeasurer working from there.
Edit
This doesn't work the way react-virtualized creator says it should or the infinite loading example implies.
Calls:
- render(): rowCount = 1
- _rowRenderer(index = 0)
- _isRowLoaded(index = 0)
- _loadMoreRows(startIndex = 0, stopIndex = 0)
- _rowRenderer(index = 0)
- end
Do I need to specify a batch size or some other props?
class HistoryBrowser extends React.Component
{
constructor(props,context,updater)
{
super(props,context,updater);
this.eventEmitter = new EventEmitter();
this.eventEmitter.extend(this);
this.state = {
history: []
};
this._cache = new Infinite.CellMeasurerCache({
fixedWidth: true,
minHeight: 50
});
this._timeoutIdMap = {};
_.bindAll(this,'_isRowLoaded','_loadMoreRows','_rowRenderer');
}
render()
{
let rowCount = this.state.history.length ? (this.state.history.length + 1) : 1;
return <Infinite.InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={rowCount}
>
{({ onRowsRendered, registerChild }) =>
<Infinite.AutoSizer disableHeight>
{({ width }) =>
<Infinite.List
ref={registerChild}
deferredMeasurementCache={this._cache}
height={200}
onRowsRendered={onRowsRendered}
rowCount={rowCount}
rowHeight={this._cache.rowHeight}
rowRenderer={this._rowRenderer}
width={width}
/>}
</Infinite.AutoSizer>}
</Infinite.InfiniteLoader>
}
_isRowLoaded({ index }) {
if (index == 0 && !this.state.history.length)
// No data yet, force load
return false;
}
_loadMoreRows({ startIndex, stopIndex }) {
let self = this;
for (let i = startIndex; i <= stopIndex; i++) {
this.state.history[startIndex] = {loading: true};
}
const timeoutId = setTimeout(() => {
delete this._timeoutIdMap[timeoutId];
for (let i = startIndex; i <= stopIndex; i++) {
self.state.history[i] = {loading: false, text: 'Hi ' + i };
}
promiseResolver();
}, 10000);
this._timeoutIdMap[timeoutId] = true;
let promiseResolver;
return new Promise(resolve => {
promiseResolver = resolve;
});
}
_rowRenderer({ index, key, style }) {
let content;
if (index >= this.state.history.length)
return <div>Placeholder</div>
else if (this.state.history[index].loading) {
content = <div>Loading</div>;
} else {
content = (
<div>Loaded</div>
);
}
return (
<Infinite.CellMeasurer
cache={this._cache}
columnIndex={0}
key={key}
rowIndex={index}
>
<div key={key} style={style}>{content}</div>
</Infinite.CellMeasurer>
);
}
}