重置行高会导致计算出不正确的行偏移量

Resetting row heights causes incorrect row offset to get calculated

InfiniteLoader 中我有一个 List,它的 rowRenderer 回调创建了一个 <div>CellMeasurer 包裹(我也在使用缓存)。行的大小可能变化很大,但此设置非常适合滚动目的。

但是,每行中的元素可以根据用户输入动态改变高度。在这些情况下,我调用:

cellMeasurerCache.clear(rowIndex, 0);
this._listRef.recomputeRowHeights(rowIndex);

但在某些情况下,这会导致行跳动 -- 这是因为 top 值计算不正确。例如,我正在显示一个文档,其中包含 List:

中呈现的以下行
rowIdx        height       top
  3            668px       420px
  4           8547        1088
  5           2420        9635

然后 4 行的高度略有增加 (~50px)。在 运行 上面的代码和 rowIndex == 4 之后,我看到以下行:

rowIdx        height       top
  5           2420px      3088px
  6           1156        5508
  7           4718        6664
  8           1050       11382

如您所见,行 5 现在有一个不正确的 top 值,导致行跳来跳去。我假设 4 行的高度没有得到正确测量。

怎么了?


2017-11-08更新: 貌似调用cellMeasurerCache.clear(rowIndex, 0)把那行的高度替换成了estimatedRowSize的值,很不同的。它似乎没有重新测量,与文档所说的相反。

CellMeasurer._maybeMeasureCell() 在获得默认高度后不会为行 4 调用。我的 rowRenderer 回调(围绕我的内容创建 CellMeasurer)仅从第 5 行开始调用。所以代码已经决定显示哪些行,行 4 具有更小的默认高度,而不是事先计算。

不确定这是否是 correct/best 处理此问题的方法,但我能够像这样工作:

首先,我使用了 CellMeasurer 的回调版本,存储 measure 回调供以后使用(每行存储):

rowRenderer = ({ key, index, style, isScrolling, parent }) => {
  const getContent = measure => {
    // store callback for later use
    this._measureCallbacks[index] = measure;

    // ... get your content ...
    return content;
  };

  return (
    <CellMeasurer
      key={key}
      cache={cellMeasurerCache}
      columnIndex={0}
      parent={parent}
      rowIndex={index}
    >
      {({ measure }) => (
        <div key={key} style={style}>
          {getContent(measure)}
        </div>
      )}
    </CellMeasurer>
  );
};

稍后,当行高发生变化时,我没有调用 cellMeasurerCache.clear(),而是 运行:

// tell row to re-measure
this._measureCallbacks[rowIndex]();
// tell list to recompute row offsets
this._listRef.recomputeRowHeights(minRow);