加载时未调用 loadMoreRows

loadMoreRows not called on load

我有以下示例实现 InfiniteLoaderTable。问题是 loadMoreRows 不会在加载时或安装组件时调用。但是,如果我手动执行 API 调用并通过 props 传递结果,loadMoreRows 将使用 startIndex 0 调用,因此我有相同的 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 to determine if it needs to be loaded. If isRowLoaded returns false, then that row is queued up and loadMoreRows is called in chunks for each range of unloaded rows.

在你上面的例子中,我 相信 发生的事情是你没有将任何初始行传递给 Table- 所以 Grid 不是最初渲染任何东西(因为它没有要渲染的行),所以我上面链接的 rows-loaded 调用者没有什么要迭代的,也没有什么要加载的。你在这里有几个选择——要么自己开始第一次加载,要么添加一个 +1 空行来提示 InfiniteLoader 它应该请求更多数据 (like I do in this example)。