React-Window 虚拟化滚动

React-Window 使用指南

React-Window ​ 是一个用于高效渲染大型列表和表格数据的 React 库,通过虚拟化滚动技术,只渲染当前可见区域的内容,从而显著提升性能。以下是它的核心用法和官方资源:


1. 官方文档

React-Window 的官方文档非常详细,地址如下:

👉 ​​React-Window 官方文档​

(由库作者 bvaughn维护)

文档包含:

  • API 参考​:所有组件和属性的详细说明。

  • 示例代码​:多种场景的实时演示(如列表、网格、动态高度等)。

  • 性能对比​:与传统渲染方式的性能差异演示。


2. 核心组件与用法

React-Window 提供两个核心组件:

1. ​**FixedSizeList**​(固定高度的列表)

适用于每行高度相同的列表。

复制代码
import { FixedSizeList as List } from 'react-window';

const Row = ({ index, style }) => (
  <div style={style}>Row {index}</div>
);

const ExampleList = () => (
  <List
    height={500}    // 列表可视区域高度
    itemCount={1000} // 总行数
    itemSize={35}    // 每行高度(固定值)
    width={300}      // 列表宽度
  >
    {Row}           // 行渲染组件
  </List>
);
2. ​**VariableSizeList**​(动态高度的列表)

适用于每行高度不同的情况(需提前知道各行高度)。

复制代码
import { VariableSizeList as List } from 'react-window';

const rowHeights = new Array(1000)
  .fill(true)
  .map(() => 25 + Math.round(Math.random() * 50));

const Row = ({ index, style }) => (
  <div style={style}>Row {index} (Height: {rowHeights[index]}px)</div>
);

const ExampleList = () => (
  <List
    height={500}
    itemCount={1000}
    itemSize={index => rowHeights[index]} // 动态获取行高
    width={300}
  >
    {Row}
  </List>
);

3. 其他常用组件

  • ​**FixedSizeGrid** ​ / ​**VariableSizeGrid**​:用于二维表格布局。

  • ​**areEqual** ​:用于优化行组件的渲染(类似 React.memo)。


4. 关键特性

  1. 虚拟化渲染​:仅渲染可视区域内的行,避免 DOM 节点过多。

  2. 平滑滚动​:通过预估滚动位置和动态加载,保持流畅体验。

  3. 支持动态高度 ​:需配合 itemSize函数或外部缓存(如 itemSizeCache)。

  4. 方向控制 ​:支持水平 (layout="horizontal") 或垂直滚动。


5. 常见问题解决

问题 1:动态高度列表闪烁?
  • 原因​:行高未预先计算,滚动时动态调整导致布局抖动。

  • 解决​:

    • 提前测量行高(如通过 itemSize函数返回准确值)。

    • 使用 react-window-infinite-loader分批次加载数据。

问题 2:如何实现无限滚动?
  • 结合 react-window-infinite-loader

    复制代码
    import InfiniteLoader from 'react-window-infinite-loader';
    
    const loadMoreItems = () => { /* 加载更多数据 */ };
    
    <InfiniteLoader
      itemCount={itemCount}
      isItemLoaded={index => items[index]}
      loadMoreItems={loadMoreItems}
    >
      {({ onItemsRendered, ref }) => (
        <List
          ref={ref}
          onItemsRendered={onItemsRendered}
          {/* 其他属性 */}
        />
      )}
    </InfiniteLoader>

6. 替代方案对比

特点
react-window 轻量级(<5KB),适合已知行高的列表/网格
react-virtualized 功能更全(支持自动高度、树形结构等),但体积较大(~15KB)
tanstack-virtual 框架无关(支持 React/Solid/Vue),现代 API 设计

完整示例代码

复制代码
import React from 'react';
import { FixedSizeList as List } from 'react-window';

const data = Array.from({ length: 1000 }, (_, i) => `Item ${i + 1}`);

const App = () => (
  <List
    height={400}
    itemCount={data.length}
    itemSize={50}
    width={300}
  >
    {({ index, style }) => (
      <div style={{ ...style, borderBottom: '1px solid #ccc' }}>
        {data[index]}
      </div>
    )}
  </List>
);

export default App;

总结

  • 使用场景​:长列表、大数据表格、下拉选择框等需要高性能滚动的场景。

  • 性能关键 ​:确保 itemSize准确(动态高度需额外处理),避免行组件不必要的重渲染。

  • 扩展工具 ​:搭配 react-window-infinite-loaderreact-window-scroller满足复杂需求。

如果需要更复杂的交互(如拖拽排序),可以考虑结合 react-dnd等库实现。

相关推荐
纸上的彩虹17 分钟前
半年一百个页面,重构系统也重构了我对前端工作的理解
前端·程序员·架构
be or not to be44 分钟前
深入理解 CSS 浮动布局(float)
前端·css
LYFlied1 小时前
【每日算法】LeetCode 1143. 最长公共子序列
前端·算法·leetcode·职场和发展·动态规划
老华带你飞1 小时前
农产品销售管理|基于java + vue农产品销售管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
小徐_23331 小时前
2025 前端开源三年,npm 发包卡我半天
前端·npm·github
GIS之路2 小时前
GIS 数据转换:使用 GDAL 将 Shp 转换为 GeoJSON 数据
前端
JIngJaneIL2 小时前
基于springboot + vue房屋租赁管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
天天扭码2 小时前
以浏览器多进程的角度解构页面渲染的整个流程
前端·面试·浏览器
你们瞎搞3 小时前
Cesium加载20GB航测影像.tif
前端·cesium·gdal·地图切片