【问题标题】:Resetting row heights causes incorrect row offset to get calculated重置行高会导致计算不正确的行偏移
【发布时间】:2018-04-20 12:05:00
【问题描述】:

InfiniteLoader 内部,我有一个List,它的rowRenderer 回调创建了一个由CellMeasurer 包装的<div>(我也为此使用了缓存)。行的大小可以变化很大,但这种设置非常适合滚动。

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

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 月 8 日更新: 似乎调用 cellMeasurerCache.clear(rowIndex, 0) 会将该行的高度替换为 estimatedRowSize 的值,这是非常不同的。它似乎没有重新测量,与文档所说的相反。

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

【问题讨论】:

  • "看来调用cellMeasurerCache.clear(rowIndex, 0) 会将该行的高度替换为estimatedRowSize 的值,这是非常不同的。它似乎没有重新测量,与文档相反说。”这是对的。此方法清除缓存的测量值,以便在下次渲染单元时重新测量。随后对list.recomputeRowHeights 的调用将重新渲染,从而触发测量。至少它应该是这样工作的。如果这没有发生,听起来可能有错误。
  • 对,我没看到。调用list.recomputeRowHeights 时应该在哪里调用CellMeasurer?在单步执行代码时,我只看到它使用了默认值。
  • 我不久前写了这个应用程序作为概念证明:tweets.now.sh
  • 也许对你有帮助?

标签: react-virtualized


【解决方案1】:

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

首先,我使用了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);

【讨论】:

  • 你能帮帮我吗?我也有同样的问题。 this._measureCallbacks 是什么?你能解释一下吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
  • 2012-03-31
  • 1970-01-01
  • 1970-01-01
  • 2013-08-24
相关资源
最近更新 更多