react虚拟滚动

复制代码
function VirtualList({ data, itemHeight, bufferSize = 5 }) {
  const [scrollTop, setScrollTop] = useState(0);
  const containerRef = useRef(null);
  
  // 计算可视区域范围
  const viewportHeight = containerRef.current?.clientHeight || 0;
  const startIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - bufferSize);
  const endIndex = Math.min(data.length, startIndex + Math.ceil(viewportHeight / itemHeight) + bufferSize * 2);

  // 动态渲染的条目
  const visibleItems = data.slice(startIndex, endIndex);

  return (
    <div 
      ref={containerRef}
      onScroll={(e) => setScrollTop(e.target.scrollTop)}
      style={{ height: '100%', overflow: 'auto' }}
    >
      {/* 占位容器,模拟完整列表高度 */}
      <div style={{ height: `${data.length * itemHeight}px` }}>
        {/* 实际渲染的内容 */}
        <div style={{ transform: `translateY(${startIndex * itemHeight}px)` }}>
          {visibleItems.map((item, index) => (
            <div key={item.id} style={{ height: `${itemHeight}px` }}>
              {item.content}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
  1. 缓冲区(bufferSize)​​:在可视区域外额外渲染少量条目,避免快速滚动时出现空白。

    1. 定高(itemHeight)​​:提前确定条目高度(或使用动态高度预测),简化位置计算。
    1. CSS Transform ​:用 translateY替代 top属性,利用GPU加速提升性能。
相关推荐
一点一木20 小时前
深度体验TRAE SOLO移动端7天:作为独立开发者,我把工作流揣进了兜里
前端·人工智能·trae
天外飞雨道沧桑21 小时前
TypeScript 中 omit 和 record 用法
前端·javascript·typescript
Lee川21 小时前
mini-cursor 揭秘:从 Tool 定义到 Agent 循环的完整实现
前端·人工智能·后端
canonical_entropy1 天前
从 Spec-Driven Development 到 Attractor-Guided Engineering
前端·aigc·ai编程
研☆香1 天前
聊聊前端页面的三种长度单位
前端
给钱,谢谢!1 天前
React + PixiJS 实现果园成长页:从状态机到浇水动画
前端·react.js·前端框架
暗冰ཏོ1 天前
VUE面试题大全
前端·javascript·vue.js·面试
次元工程师!1 天前
LangFlow开发(三)—Bundles组件架构设计(3W+字详细讲解)
java·前端·python·低代码·langflow
Bug-制造者1 天前
现代Web应用全栈开发:从架构设计到部署落地实战
前端
青春喂了后端1 天前
IntelliGit 前端状态层重构:把一个全局 Store 拆成清晰的状态边界
前端·重构·状态模式