2017-02-13 12 views
1

InfiniteLoaderを実装する次の例はTableです。問題は、ロード時またはコンポーネントのマウント時にloadMoreRowsが呼び出されないことです。しかし、私は手動でAPI呼び出しを実行し、結果をpropsに渡すと、startIndex 0でloadMoreRowsが呼び出され、同じAPIコールが2回発生します。loadMoreRowsがロード時に呼び出されない

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 
       }); 
      }); 
    } 
}; 

答えて

1

問題がloadMoreRows負荷時や部品が実装されている上で呼び出されないことです。それがロードする必要があるかどうかを決定する

Any time a range of rows loadsInfiniteLoadercalls isRowLoaded for each rowisRowLoadedがfalseを返すと、その行はキューに入れられ、loadMoreRows is called in chunks for each range of unloaded rowsとなります。上記のあなたのケースでは

、私は何が起こっていることはあなたがTableに任意の初期の行を渡していないということですを信じ- そうGridは最初は何もレンダリングされませんので、rows-(それがレンダリングする行がありませんので)上にリンクされたロードされた呼び出し元は、何度も繰り返し処理する必要はありません。ここにはいくつかのオプションがあります。最初のロードを自分で開始するか、または空の行を追加しての先端に追加のデータ(like I do in this example)をリクエストする必要があります。

+0

私は、初期ログ用にロードするようにステータスを設定していないという問題があったと思います。ありがとう、この部分は今動作します! – XeniaSis

関連する問題