gpt4 book ai didi

reactjs - 如何在 react 虚拟化表中使用 CellMeasurer?

转载 作者:行者123 更新时间:2023-12-03 13:36:22 31 4
gpt4 key购买 nike

我使用 react-virtualized Table 来渲染一个包含多行的表。由于固定的列宽,我不希望我的长文本被修剪,所以我想使用 CellMeasurer 来动态测量宽度。

这是一个使用 Grid 的示例。它工作正常。

render() {
const {width} = this.props;

return (
<Grid
className={styles.BodyGrid}
columnCount={1000}
columnWidth={this._cache.columnWidth}
deferredMeasurementCache={this._cache}
height={400}
overscanColumnCount={0}
overscanRowCount={2}
cellRenderer={this._cellRenderer}
rowCount={50}
rowHeight={35}
width={width}
/>
);
}

但都没有 Table也不是 ColumndeferredMeasurementCache支柱。我当前的代码如下所示:
return (
<div>
<AutoSizer disableHeight>
{({width}) => (
<Table
ref="Table"
disableHeader={disableHeader}
headerClassName={styles.headerColumn}
headerHeight={headerHeight}
height={height}
noRowsRenderer={this._noRowsRenderer}
overscanRowCount={overscanRowCount}
rowClassName={this._rowClassName}
rowHeight={useDynamicRowHeight ? this._getRowHeight : rowHeight}
rowGetter={rowGetter}
rowCount={rowCount}
scrollToIndex={scrollToIndex}
sort={this._sort}
sortBy={sortBy}
sortDirection={sortDirection}
width={width}>
<Column
label="Index"
cellDataGetter={({rowData}) => rowData.index}
dataKey="index"
disableSort={!this._isSortEnabled()}
width={60}
/>
<Column .../>
</Table>
)}
</Autosizer>
</div>
);

我如何使用 Measurer在表?

最佳答案

react-virtualized 的文档化 API 不支持使用 CellMeasurerTable .这在 react 虚拟化中留下了一些选项,包括:

  • 使用 Grid 实现和外部列标题
  • 使用 Table 实现API 中未记录对内部组件的依赖

  • 下面概述了后一种方法的解决方案,适用于 react-virtualized v9.21.1(截至 2019 年 7 月的最新版本)。当然,这种方法有风险,即在 future 版本的 react-virtualized 中更改内部结构会破坏某些东西。

    有几个问题需要处理,包括:
  • Table使用 Grid在内部提供虚拟化滚动,但不会在需要的地方在 API 中公开它。
  • Grid只有一列,其中包含所有 Column一行中的单元格,但 Grid作为渲染的父级传递 Column细胞。结果,一个Grid单元格可以关联很多 Column细胞,这种情况GridCellMeasurer不支持。
  • 使用 CellMeasurerGrid取决于 Grid直接管理一行中的所有单元格,无需干预 rowRenderer , 而 Table有自己的行渲染逻辑。

  • [在下面的代码示例中,一些数据元素和函数用模块级声明显示。实际上,它们可以被定义为包含 Table 的组件的成员。或者在某些情况下,可能作为 Prop 传递给包含 Table 的组件。 .]

    以下解决方案在一般情况下解决了这些问题:
  • 静态表数据
  • 静态行、列和单元格格式
  • 列中单元格的高度在行之间是可变的
  • 多列可以有这样的可变高度单元格

  • 在这种情况下,使用了 CellMeasurerCache 的两个实例。 cellCache是个人高度 Column细胞。 rowCache是用于行的高度。
    const cellCache = new CellMeasurerCache({
    fixedWidth: true,
    defaultHeight: 20, // keep this <= any actual row height
    minHeight: 10, // keep this <= any actual row height
    });

    const rowCache = new CellMeasurerCache({
    fixedWidth: true,
    defaultHeight: 37, // tune as estimate for unmeasured rows
    minHeight: 10, // keep this <= any actual row height
    });

    对于 Table成分:
  • 添加 rowCache作为 deferredMeasurementCache Prop
  • 添加 rowRenderer功能
  • 添加 rowHeight功能
  •   <Table
    ...
    deferredMeasurementCache={rowCache}
    rowRenderer={rowRenderer}
    rowHeight={rowHeight}
    >

    后面会介绍这些功能。 Table不会对 deferredMeasurementCache 做任何事情除了将它作为 Prop 传递给 TableGrid .

    Column需要测量的,加一个 cellRenderer功能。在许多更简单的情况下,相同的函数可用于所有测量列:
      <Column
    ...
    cellRenderer={measuredCellRenderer}
    />

    为了帮助协调两个缓存的使用,需要三个额外的数据项:
    const aMeasuredColumnIndex = 2; // any measured column index will do

    let rowParent = null; // let a cellRenderer supply a usable value

    const cellParent = { // an intermediary between measured row cells
    // and their true containing Grid
    invalidateCellSizeAfterRender: ({rowIndex}) => {
    if (rowParent &&
    typeof rowParent.invalidateCellSizeAfterRender == 'function') {
    rowParent.invalidateCellSizeAfterRender({columnIndex: 0, rowIndex});
    }
    },
    }
    rowParent用于将表格的网格暴露给 rowRenderer。 cellParent作为两个缓存之间和行之间的中介,其 Column单元格,以及 TableGrid .

    接下来是前面提到的三个函数:
    function measuredCellRenderer({rowIndex, columnIndex, parent, cellData}) {
    rowParent = parent; // parent is the Table's grid,
    // save it for use by rowRenderer
    return (
    <CellMeasurer
    cache={cellCache}
    columnIndex={columnIndex}
    parent={cellParent}
    rowIndex={rowIndex}
    >
    <div>{cellData}</div>
    </CellMeasurer>
    );
    // Note: cellData is wrapped in a <div> to facilitate height
    // styling, for example adding padding to the <div>, because CellMeasurer
    // measures the height of the content box.
    }

    function rowRenderer(params) {
    return (
    <CellMeasurer
    cache={rowCache}
    columnIndex={0}
    key={params.key}
    parent={rowParent}
    rowIndex={params.rowIndex}
    >
    {Table.defaultProps.rowRenderer(params)}
    </CellMeasurer>
    );
    }

    function rowHeight({index}) {
    let cellCacheRowHeight = cellCache.rowHeight({index});
    if (cellCache.has(index, aMeasuredColumnIndex)) {
    rowCache.set(index, 0, 20, cellCacheRowHeight);
    // the 20 above is a somewhat arbitrary number for width,
    // which is not relevant
    }
    return cellCacheRowHeight;
    }

    请注意, CellMeasurer 有两种不同的用法。 .一个是在 measuredCellRenderer里面功能和用途 cellCachecellParent .另一个在 rowRenderer里面功能和用途 rowCacherowParent .

    另外, rowHeight函数不只是报告行的高度。它还负责传输行的 rowHeightcellCacherowCache 中第一列也是唯一一列的行单元格高度.

    当表只有一个测量列时,可以稍微简化此解决方案。只有一个 CellMeasurerCache需要。单个缓存可以满足
    两者的作用 cellCacherowCache .其结果:
  • 不需要cellParent ;它可以被移除。引用 cellParent可以替换为对 rowParent 的引用,或者在 measuredCellRenderer 的情况下函数,CellMeasurer parent prop 可以直接设置为 parent函数参数。
  • measuredCellRenderer , CellMeasurer需要为 columnIndex={0} 进行硬编码,即使被测列不是表中的第一列。
  • if rowHeight里面的声明由于无需在两个缓存之间传输高度,因此可以删除该功能。
  • aMeasuredColumnIndex可以删除,因为它只在 rowHeight 中被引用if陈述。
  • 关于reactjs - 如何在 react 虚拟化表中使用 CellMeasurer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51826454/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com