2016-12-30 4 views
3

私はStackOverflowで多くの回答をしました。私はまた、リスト文書here react-virtualized/Listを見てきました。しかし、まだ私は動的に行の高さを設定する方法を理解することができません反応仮想化リスト。高さを計算する方法rowHeight小道具?反応仮想化リストで動的行の高さを設定するにはどうすればよいですか?

rowHeight={({ index }) => this.computeRowHeight({ index })}のように私の機能を呼び出すことができます。しかし、関数はどのように行の高さを計算しますか?

以下は参考用のコードです。

import React, { Component } from 'react'; 
import ReactDOM from 'react-dom'; 
import { AutoSizer, InfiniteLoader, List } from 'react-virtualized'; 
import _ from 'lodash'; 

class InfiniteList extends Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     list: props.list, 
     loading: false 
    }; 
    } 
    componentDidMount() { 
    fetch('http://jsonplaceholder.typicode.com/comments') 
     .then((response) => { 
     response.json().then((data) => { 
      this.setState({ 
      list: _.concat(this.state.list, _.map(data, 'body')), 
      loading: false 
      }); 
     }); 
     }); 
    } 
    isRowLoaded({ index }) { 
    return !!this.state.list[index]; 
    } 

    loadMoreRows({ startIndex, stopIndex }) { 
    if (this.state.loading) { 
     return; 
    } 
    this.setState({ 
     loading: true 
    }); 
    return fetch('http://jsonplaceholder.typicode.com/comments') 
     .then((response) => { 
     response.json().then((data) => { 
      // Simulate delay 
      setTimeout(() => { 
      this.setState({ 
       list: _.concat(this.state.list, _.map(data, 'body')), 
       loading: false 
      }); 
      }, 3000); 
     }); 
     }); 
    } 

    rowRenderer({ key, index, isScrolling, isVisible, style }) { 
    if (isVisible) { 
     return (
     <div key={key}> 
      <div style={style}>#{this.state.list[index]}.</div> 
     </div> 
    ); 
    } 
    } 

    render() { 
    return (
     <div> 
     <InfiniteLoader 
      isRowLoaded={({ index }) => this.isRowLoaded({ index })} 
      loadMoreRows={({ startIndex, stopIndex }) => this.loadMoreRows({ startIndex, stopIndex })} 
      rowCount={this.state.list.length} 
     > 
      {({ onRowsRendered, registerChild }) => (
      <AutoSizer disableHeight> 
       {({ width }) => (
       <List 
        onRowsRendered={onRowsRendered} 
        ref={registerChild} 
        width={width} 
        height={320} 
        rowCount={this.state.list.length} 
        rowHeight={40} 
        rowRenderer={({ key, index, isScrolling, isVisible, style }) => this.rowRenderer({ key, index, isScrolling, isVisible, style })} 
       /> 
      )} 
      </AutoSizer> 
     )} 
     </InfiniteLoader> 
     {this.state.loading && <p>Loading...</p>} 
     </div> 
    ); 
    } 
} 

const list = []; 

ReactDOM.render(
    <InfiniteList list={list} />, 
    document.querySelector('#root') 
); 

更新

ダイナミック高さは今CellMeasurerと、次のコードで働いています。しかし、残念なことにthis.loadMoreRows()関数はInfiniteLoaderで呼び出されていません。 CellMeasurerもなく、それは動作していません。私は次のコードで何が間違っているのか分かりません。

import React, { Component } from 'react'; 
import { AutoSizer, CellMeasurer, InfiniteLoader, List } from 'react-virtualized'; 
import _ from 'lodash'; 

class InfiniteList extends Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     list: props.list, 
     loading: false 
    }; 
    } 
    componentDidMount() { 
    fetch('http://jsonplaceholder.typicode.com/comments') 
     .then((response) => { 
     response.json().then((data) => { 
      this.setState({ 
      list: _.concat(this.state.list, _.map(data, 'body')), 
      loading: false 
      }); 
     }); 
     }); 
    } 
    isRowLoaded({ index }) { 
    return !!this.state.list[index]; 
    } 

    loadMoreRows({ startIndex, stopIndex }) { 
    if (this.state.loading) { 
     return; 
    } 
    this.setState({ 
     loading: true 
    }); 
    return fetch('http://jsonplaceholder.typicode.com/comments') 
     .then((response) => { 
     response.json().then((data) => { 
      // Simulate delay 
      setTimeout(() => { 
      this.setState({ 
       list: _.concat(this.state.list, _.map(data, 'body')), 
       loading: false 
      }); 
      }, 3000); 
     }); 
     }); 
    } 

    rowRenderer({ key, index, isScrolling, isVisible, style }) { 
    if (isVisible) { 
     return (
     <div key={key} style={style}>#{index} {this.state.list[index]}.</div> 
    ); 
    } 
    } 
    cellRenderer({ columnIndex, key, rowIndex, style }) { 
    return (
     <div 
     key={key} 
     style={style} 
     > 
     <div>#{rowIndex} {this.state.list[rowIndex]}.</div> 
     </div> 
    ); 
    } 
    render() { 
    return (
     <div> 
     <InfiniteLoader 
      isRowLoaded={isRowLoaded => this.isRowLoaded(isRowLoaded)} 
      loadMoreRows={loadMoreRows => this.loadMoreRows(loadMoreRows)} 
      rowCount={this.state.list.length} 
     > 
      {({ onRowsRendered, registerChild }) => (
      <AutoSizer disableHeight> 
       {({ width }) => (
       <CellMeasurer 
        cellRenderer={cellRenderer => this.cellRenderer(cellRenderer)} 
        columnCount={1} 
        rowCount={this.state.list.length} 
       > 
        {({ getRowHeight }) => (
        <List 
         onRowsRendered={onRowsRendered} 
         ref={registerChild} 
         width={width} 
         height={400} 
         rowCount={this.state.list.length} 
         rowHeight={getRowHeight} 
         rowRenderer={rowRenderer => this.rowRenderer(rowRenderer)} 
        /> 
       )} 
       </CellMeasurer> 
      )} 
      </AutoSizer> 
     )} 
     </InfiniteLoader> 
     {this.state.loading && <p>Loading...</p>} 
     </div> 
    ); 
    } 
} 

const list = []; 

ReactDOM.render(
    <InfiniteList list={list} />, 
    document.querySelector('#root') 
); 

助けてください。ありがとう!

答えて

0

行の高さを確認するには、computeRowHeightと記述する必要があります。場合によっては、その行のインデックスとプロパティに基づいて、行の高さを知ることができます。たとえば、行が異なるコンポーネントである場合、特定の行が高さ40のコンポーネントAであり、別の行が高さ60のコンポーネントBであることがわかっている場合、それらの小道具をチェックして正しい高さを戻すことができます。

高さがわからない場合は、DOMの要素を実際に見て、その高さを把握する必要があります。 DOMにまだ存在していない場合は、最初に最善の推測を返し、レンダリング後にrecomputeRowHeightsに電話してDOMを検査する必要があります。

+1

Drewの答えに加えて、コンテンツのサイズについてわからない場合は、CellMeasurerのような別の反応仮想化コンポーネントを使用することもできます。私はまた、反応測定を使用している人に、反応が良いと評価され、良い結果が得られたと聞いています。 – brianvaughn

+0

@brianvaughnありがとう!以前は、CellMeasurerで動的な高さを得ることができませんでした。しかし、私はもう一度試してみましたが、現在は動作しています(時には重なり合う行はほとんどありません)。しかし、残念ながら、私の 'this.loadMoreRows()'関数はInfiniteLoaderで呼び出されていません。私はCellMeasurerの前でもうまくいきませんでした。したがって、CellMeasurerとは何の関係もありません。私はここで何が間違っているのか分かりません。御時間ありがとうございます! – krishnaxv

+0

私はこれを理解しました。 'rowCount = {this.state.list.length} 'ではなく、' InfiniteLoader'の 'rowCount'に任意の高い数値を与えなければなりません。 – krishnaxv

関連する問題