所有分类
  • 所有分类
  • Html5资源
  • React资源
  • Vue资源
  • Php资源
  • ‌小程序资源
  • Python资源

react-window 大数据列表和表格数据渲染组件之虚拟滚动

简介

React Window 是一个高效的 React 组件库,专为渲染大数据列表和表格数据而设计。它通过”虚拟化”技术(也称为”窗口化”或”列表虚拟化”)解决了在 React 应用中渲染大量数据时的性能问题。与传统方法不同,React Window 只渲染用户当前可见的元素,而不是整个列表,从而显著提高了渲染性能和内存使用效率。

主要特性

  • 高性能渲染:只渲染可视区域内的元素,大幅提升性能
  • 灵活的布局:支持固定大小和可变大小的列表项
  • 多种列表类型:支持垂直列表、水平列表和网格布局
  • 轻量级:体积小,依赖少,易于集成
  • 滚动优化:平滑的滚动体验,支持自动滚动到指定位置
  • TypeScript 支持:完整的类型定义

安装方法

npm install react-window
# 或
yarn add react-window

使用示例

固定大小的列表

import { FixedSizeList } from "react-window";

const Example = () => {
  const items = Array(1000)
    .fill()
    .map((_, index) => `Item ${index}`);

  const Row = ({ index, style }) => (
    <div
      style={style}
      className="px-4 py-2 border-b border-gray-200 hover:bg-gray-50 transition-colors cursor-pointer"
    >
      {items[index]}
    </div>
  );

  return (
    <div className="flex justify-center items-center min-h-screen bg-gray-100">
      <div className="bg-white rounded-lg shadow-lg overflow-hidden">
        <FixedSizeList
          height={400}
          width={300}
          itemCount={items.length}
          itemSize={40}
          className="scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100"
        >
          {Row}
        </FixedSizeList>
      </div>
    </div>
  );
};

export default Example;

可变大小的列表

import { VariableSizeList } from "react-window";

const Example = () => {
  const items = Array(1000)
    .fill()
    .map((_, index) => `Item ${index}`);

  // 根据索引返回不同的高度
  const getItemSize = (index) => {
    return 35 + (index % 3) * 15; // 35, 50, 65 像素的交替高度
  };

  const Row = ({ index, style }) => (
    <div
      style={style}
      className={`
        px-4 py-2 
        ${index % 2 === 0 ? "bg-gray-50" : "bg-white"}
        hover:bg-blue-50 
        transition-colors
        border-b border-gray-200
        cursor-pointer
        flex items-center
        text-gray-700
        hover:text-blue-600
      `}
    >
      <span className="mr-3 text-sm font-medium">{index + 1}.</span>
      {items[index]}
    </div>
  );

  return (
    <div className="flex justify-center items-center min-h-screen bg-gray-100">
      <div className="border border-gray-200 rounded-md overflow-hidden">
        <VariableSizeList
          height={400}
          width={300}
          itemCount={items.length}
          itemSize={getItemSize}
          className="scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100"
        >
          {Row}
        </VariableSizeList>
      </div>
    </div>
  );
};

export default Example;

网格布局

import { FixedSizeGrid } from "react-window";

const Example = () => {
  const Cell = ({ columnIndex, rowIndex, style }) => (
    <div
      style={style}
      className="border border-gray-200 p-2 bg-white hover:bg-gray-50 transition-colors duration-200 flex items-center justify-center text-sm text-gray-600"
    >
      Item {rowIndex},{columnIndex}
    </div>
  );

  return (
    <div className="flex justify-center items-center min-h-screen bg-gray-100">
      <FixedSizeGrid
        columnCount={100}
        columnWidth={100}
        height={400}
        rowCount={100}
        rowHeight={35}
        width={300}
        className="bg-white rounded border border-gray-300"
      >
        {Cell}
      </FixedSizeGrid>
    </div>
  );
};

export default Example;

高级用法

结合 react-virtualized-auto-sizer 自适应容器大小

import { FixedSizeList } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";

const Example = () => {
  const items = Array(1000)
    .fill()
    .map((_, index) => `Item ${index}`);

  const Row = ({ index, style }) => (
    <div
      style={style}
      className="px-4 py-2 border-b border-gray-200 hover:bg-gray-50 transition-colors duration-200"
    >
      <span className="text-gray-800 font-medium">{items[index]}</span>
    </div>
  );

  return (
    <div className="h-screen w-full bg-white shadow-lg rounded-lg overflow-hidden mt-7">
      <AutoSizer>
        {({ height, width }) => (
          <FixedSizeList
            className="scrollbar-thin scrollbar-thumb-gray-400 scrollbar-track-gray-100"
            height={height - 64} // Subtract header height
            width={width}
            itemCount={items.length}
            itemSize={45}
          >
            {Row}
          </FixedSizeList>
        )}
      </AutoSizer>
    </div>
  );
};

export default Example;

使用 useRef 和 scrollToItem 方法

import { useRef } from "react";
import { FixedSizeList } from "react-window";

const Example = () => {
  const listRef = useRef();
  const items = Array(1000)
    .fill()
    .map((_, index) => `Item ${index}`);

  const scrollToItem = (index) => {
    listRef.current.scrollToItem(index, "center");
  };

  return (
    <div className="p-6 max-w-md mx-auto bg-white rounded-xl">
      <div className="space-x-4 mb-6">
        <button
          onClick={() => scrollToItem(50)}
          className="bg-blue-500 hover:bg-blue-600 text-white font-semibold py-2 px-4 rounded-lg transition duration-200"
        >
          滚动到第50项
        </button>
        <button
          onClick={() => scrollToItem(300)}
          className="bg-green-500 hover:bg-green-600 text-white font-semibold py-2 px-4 rounded-lg transition duration-200"
        >
          滚动到第300项
        </button>
      </div>

      <div className="border rounded-lg overflow-hidden">
        <FixedSizeList
          ref={listRef}
          height={620}
          width={400}
          itemCount={items.length}
          itemSize={35}
          className="scrollbar-thin scrollbar-thumb-gray-400 scrollbar-track-gray-100"
        >
          {({ index, style }) => (
            <div
              style={style}
              className="px-4 py-2 hover:bg-gray-100 transition-colors duration-150 border-b border-gray-100"
            >
              {items[index]}
            </div>
          )}
        </FixedSizeList>
      </div>
    </div>
  );
};

export default Example;

性能优化建议

  1. 使用 memoization:对列表项组件使用 React.memo 减少不必要的重渲染
  2. 避免内联样式:尽量使用 CSS 类而不是内联样式
  3. 合理设置 overscanCount:适当增加预渲染的项目数量,提升滚动体验
  4. 使用 isScrolling 参数:在快速滚动时可以显示占位符内容

与其他库的比较

  • react-virtualized:React Window 是 react-virtualized 的轻量级替代品,API 更简洁,体积更小
  • react-virtual:更现代的虚拟化库,使用 hooks API,但 React Window 更成熟稳定
  • 原生实现:相比自己实现虚拟滚动,React Window 提供了更完善的功能和更好的性能
资源下载
下载价格免费
注意:本网站资源属于虚拟产品,不支持退款。请谨慎购买! 购买后资源无法下载,请联系客服QQ:844475003,微信号:th844475003。
原文链接:https://code.ifrontend.net/archives/837,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?