You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设置react-window VariableSizeList宽度100%且高度自适应?

问题原因与修复方案

核心问题分析

  1. AutoSizer的依赖条件缺失:AutoSizer必须依赖父容器有明确的宽高约束(比如固定高度、百分比高度且父级存在可计算尺寸),否则它无法正确计算可用空间,会传给VariableSizeList宽高为0,直接导致页面空白。
  2. 虚拟列表的适配逻辑错误:你原有的getPageHeight方法依赖固定的window.innerWidth,但使用AutoSizer后,列表宽度应该跟随容器动态计算,两者不匹配会导致页面尺寸异常。

修复步骤

步骤1:给父容器添加尺寸约束

修改MemoizedPDFPreview.module.css中的样式,确保包裹AutoSizer的容器有明确的尺寸:

/* 基础预览容器样式 */
.previewBody {
  width: 100%;
  min-height: 100vh; /* 让容器至少占满视口高度 */
  overflow: hidden;
}

/* 全屏预览容器样式 */
.previewFsBody {
  width: 100%;
  height: 100vh;
  overflow: hidden;
}

步骤2:正确适配AutoSizer与VariableSizeList

更新renderPdfList方法,让列表尺寸跟随AutoSizer的计算结果,同时动态调整PDF页面的宽高:

const renderPdfList = () => {
  if (pdf && pageViewports) {
    return (
      <AutoSizer>
        {({ width, height }) => (
          <VariableSizeList
            width={width}
            height={height}
            estimatedItemSize={100}
            itemCount={pdf.numPages}
            // 直接在itemSize中根据当前宽度计算页面高度
            itemSize={(index) => {
              const pageViewport = pageViewports[index];
              const scale = width / pageViewport.width;
              return pageViewport.height * scale;
            }}
          >
            {({ index, style }) => (
              <TeXPDFPage
                index={index}
                // 确保子页面宽度匹配列表容器,继承高度样式
                style={{ ...style, width: width }}
                projId={projId}
                projAttribute={projAttribute}
              />
            )}
          </VariableSizeList>
        )}
      </AutoSizer>
    );
  } else {
    return <div>loading...</div>;
  }
};
  • 移除原来独立的width状态,改用AutoSizer返回的动态宽度计算页面高度,避免窗口尺寸变化时出现适配问题。
  • 给TeXPDFPage的样式补充width: width,确保页面宽度与列表容器完全匹配。

步骤3:窗口尺寸变化适配(可选)

如果需要在窗口 resize 时实时更新列表尺寸,可以给AutoSizer添加回调:

<AutoSizer onResize={({ width, height }) => {
  // 可在此处添加额外的尺寸监听逻辑,比如保存尺寸到状态
}}>
  {/* ... 列表内容 ... */}
</AutoSizer>

特殊场景:完全自适应内容高度

如果不需要虚拟滚动,只想让容器高度随所有PDF页面总高度自适应,可以直接渲染所有页面(适合PDF页数较少的场景):

const renderPdfList = () => {
  if (pdf && pageViewports) {
    const containerWidth = document.getElementById('pdfContainer')?.clientWidth || window.innerWidth;
    return (
      <div style={{ width: '100%' }}>
        {Array.from({ length: pdf.numPages }).map((_, index) => {
          const pageViewport = pageViewports[index];
          const scale = containerWidth / pageViewport.width;
          const height = pageViewport.height * scale;
          return (
            <TeXPDFPage
              key={index}
              index={index}
              style={{ width: containerWidth, height }}
              projId={projId}
              projAttribute={projAttribute}
            />
          );
        })}
      </div>
    );
  } else {
    return <div>loading...</div>;
  }
};

内容的提问来源于stack exchange,提问作者Dolphin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:49:50