我在 StackOverflow 上查看了很多答案。我还浏览了此处的列表文档,react-virtualized/List 。但是,我仍然无法理解如何在 react-virtualized 列表中动态设置行高。如何在rowHeight prop函数中计算高度?

我可以像 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') 
); 

Update

动态高度现在可通过 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') 
); 

任何帮助将不胜感激。谢谢!

请您参考如下方法:

您需要自己编写computeRowHeight来确定行的高度。在某些情况下,根据该行的索引和属性,您可能能够知道该行的高度。例如,如果您的行可能是不同的组件,如果您知道某一行将是高度为 40 的组件 A,另一行将是高度为 60 的组件 B,您可以检查这些 props 并返回正确的高度。

如果您不知道高度,那么您将必须实际查看 DOM 中的元素并计算出它的高度。如果 DOM 中尚不存在,您需要首先返回最佳猜测,然后调用 recomputeRowHeights然后渲染并检查 DOM。


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!