Skip to content

useVirtualList 最后一个元素的高度不能超过 container 的高度 #2496

@weekbin

Description

@weekbin

当最后一个元素的高度比 Container 还高时,getOffset 的返回值会等于 list.length

  const getOffset = (scrollTop: number) => {
    if (isNumber(itemHeightRef.current)) {
      return Math.floor(scrollTop / itemHeightRef.current) + 1;
    }
    let sum = 0;
    let offset = 0;
    for (let i = 0; i < list.length; i++) {
      const height = itemHeightRef.current(i, list[i]);
      sum += height;
      if (sum >= scrollTop) {
        offset = i;
        break;
      }
    }
    return offset + 1;
  };

在计算 visibleCount 时,会导致 getVisibleCount 的返回值为 -list.length

  const getVisibleCount = (containerHeight: number, fromIndex: number) => {
    if (isNumber(itemHeightRef.current)) {
      return Math.ceil(containerHeight / itemHeightRef.current);
    }

    let sum = 0;
    let endIndex = 0;
    for (let i = fromIndex; i < list.length; i++) {
      const height = itemHeightRef.current(i, list[i]);
      sum += height;
      endIndex = i;
      if (sum >= containerHeight) {
        break;
      }
    }
    return endIndex - fromIndex;
  };

最终会导致 start = list.length,end = overscan,会取不到元素进行渲染。

const start = Math.max(0, offset - overscan); // 起始位置
const end = Math.min(list.length, offset + visibleCount + overscan); // 结束位置

建议在 getVisibleCount 返回时增加判断 endIndex - fromIndex < 0 ? 0 : endIndex - fromIndex,
这样在最后一个元素高度比 Contianer 还大时,仍然可以保证正常的渲染。

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions