我有以下示例,使用 Table
实现 InfiniteLoader
。问题是在加载或安装组件时不会调用 loadMoreRows
。但是,如果我手动执行 API 调用并通过 props
传递结果,则使用 startIndex 0 调用 loadMoreRows
,因此我有两次相同的 API 调用。
import React = require('react');
import _ = require('lodash');
import Immutable = require('immutable');
import Api = require('./Api');
const STATUS_LOADING = 1,
STATUS_LOADED = 2,
LOG_LIMIT = 200;
interface Props {
logEntries: Immutable.List<Immutable.Map<string, any>>;
}
interface State {
logEntries?: Immutable.List<Immutable.Map<string, any>>;
count?: number;
loadedRowsMap?: any;
}
class LogViewer extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
logEntries: props.logEntries,
count: 0,
loadedRowsMap: {}
};
}
render() {
return {this.renderLoader()};
}
private renderLoader() {
const {logEntries, count} = this.state;
return (
<InfiniteLoader isRowLoaded={this.isRowLoaded.bind(this)}
loadMoreRows={this.loadMoreRows.bind(this)}
minimumBatchSize={LOG_LIMIT}
rowCount={logEntries.size} >
{
({onRowsRendered, registerChild}) => (
<AutoSizer disableHeight>
{
({width}) => (
<Table headerHeight={20}
height={400}
onRowsRendered={onRowsRendered}
ref={registerChild}
rowCount={count}
className='log-entries'
gridClassName='grid'
headerStyle={{ fontSize: 15 }}
rowGetter={({index}) => logEntries.get(index)}
rowHeight={50}
width={width} >
<Column label='Name'
key='name'
dataKey='name'
width={200} />
</Table>
)
}
</AutoSizer>
)
}
</InfiniteLoader>
);
}
private isRowLoaded({index}) {
const {loadedRowsMap} = this.state;
return !!loadedRowsMap[index];
}
private loadMoreRows({startIndex, stopIndex}) {
const {loadedRowsMap, level, logEntries} = this.state;
_.range(startIndex, stopIndex).forEach(i => {
loadedRowsMap[i] = STATUS_LOADING;
});
this.setState({ loadedRowsMap });
const offset = Math.floor((startIndex + 1) / LOG_LIMIT);
return Api.logs(LOG_LIMIT, offset)
.then(({body: [count, logs]}) => {
_.range(startIndex, stopIndex).forEach(i => {
loadedRowsMap[i] = STATUS_LOADED;
});
const newLogs = logEntries.toJS().concat(logs);
this.setState({
count,
logEntries: Immutable.fromJS(newLogs),
loadedRowsMap
});
});
}
};
最佳答案
The problem is that
loadMoreRows
is not called on load or when the component is mounted.
Any time a range of rows loads , InfiniteLoader
calls isRowLoaded
for each row来判断是否需要加载。如果 isRowLoaded
返回 false,则该行将排队并 loadMoreRows
is called in chunks for each range of unloaded rows .
在上面的例子中,我相信发生的情况是您没有将任何初始行传递到Table
- 所以Grid
是最初不渲染任何内容(因为它没有要渲染的行),因此我上面链接的行加载调用者没有任何可迭代的内容,也没有任何可加载的内容。您在这里有几个选择 - 要么自己开始第一次加载,要么添加一个 +1 空行来提示 InfiniteLoader 它应该请求更多数据 ( like I do in this example )。
关于react-virtualized - 加载时未调用 loadMoreRows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42201299/