react-virtualized实现行元素不等高的虚拟列表滚动

前言:

当一个页面中需要接受接口返回的全部数据进行页面渲染时间,如果数据量比较庞大,前端在渲染dom的过程中需要花费时间,造成页面经常出现卡顿现象。

需求:通过虚拟加载,优化页面渲染速度

优点:不需要固定行元素高度一致

行元素等高的虚拟列表实现方法
实现方法

npm 安装 react-virtualized

npm install react-virtualized --save

页面引入

import { List as VirtualizedList, AutoSizer, CellMeasurer, CellMeasurerCache } from 'react-virtualized';

Cp.jsx

javascript 复制代码
import React, { Component } from 'react';
import { List as VirtualizedList, AutoSizer, CellMeasurer, CellMeasurerCache } from 'react-virtualized';

class Cp extends Component {
  constructor(props) {
    super(props);
    this.cache = new CellMeasurerCache({
      fixedWidth: true, 
      defaultHeight: 100 // 未计算的单元格初始默认的高度
    });

    this.state = {
      viewWidth: 200,
      viewHeight: 500,
      dataList: [
        {id: 1, content1: '小灰灰学编程小灰灰学编程小灰灰学编程', content2: '小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程'},
        {id: 2, content1: '小灰灰学编程', content2: '小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程'},
        {id: 3, content1: '小灰灰学编程小灰灰学编程', content2: ''},
        {id: 4, content1: '小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程', content2: '小灰灰学编程'},
        {id: 5, content1: '小灰灰学编程', content2: ''},
        {id: 6, content1: '小灰灰学编程小灰灰学编程', content2: '小灰灰学编程'},
        {id: 7, content1: '小灰灰学编程小灰灰学编程小灰灰学编程', content2: '小灰灰学编程'},
        {id: 8, content1: '小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程', content2: '小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程'},
        {id: 9, content1: '小灰灰学编程小灰灰学编程', content2: ''},
        {id: 10, content1: '小灰灰学编程', content2: '小灰灰学编程'},
        {id: 7, content1: '小灰灰学编程', content2: '小灰灰学编程小小灰灰学编程小灰灰学编程小灰灰学编程灰小灰灰学编程灰学编程'},
        {id: 8, content1: '小灰灰学编程', content2: '小灰灰学编程小小灰灰学编程灰灰学编程'},
        {id: 9, content1: '小灰灰学编程小灰灰学编程', content2: ''},
        {id: 10, content1: '小灰灰学编程', content2: '小灰灰学编程'},
      ]
    }
  }

  componentDidUpdate() {
    // 重置所有单元格的计算缓存
    this.cache.clearAll();
  }

  /**
   * rowRenderer 渲染行元素的方法
   *    index: 索引
   *    key: 记录在数组中的位置
   *    parent: 定义该列表是另一个列表的父列表还是子列表
   *    style: 用于定位行的样式对象
   *    isVisible: 确定行是否可见或不可见
   *    isScrolling: 指示组件中是否发生滚动 List
   * 
   * CellMeasurer 自动计算单元格内容的高阶组件
   *    cache: 在CellMeasure和他们父级的Grid之间共享的缓存
   *    children: 子元素 可以是一个react元素或者函数
   *    columnIndex: 经计算的列index | 0
   *    parent: 父级Grid的引用
   *    rowIndex: 经计算的行index
   */

  rowRenderer = ({ index, key, parent, style }) =>{
    const {dataList} = this.state
    const itemData = dataList[index];
    return (
      <div key={key} style={style}>
        <CellMeasurer
          cache={this.cache}
          columnIndex={0}
          key={key}
          rowIndex={index}
          parent={parent}
        >
          <div>
            <div>{`第${itemData.id}个元素`}</div>
            <div>content1: {itemData.content1}</div>
            <div>{itemData.content2}</div>
          </div>
        </CellMeasurer>
      </div>
    );
  }

  render() {
    const {dataList} = this.state
    return (
      <div className="virtualized-list">
        <AutoSizer>
          {({ viewWidth, viewHeight }) => (
            /**
             * VirtualizedList
             *    width: 可视区域宽度
             *    height: 可视区域高度
             *    rowHeight: 行高度
             *    rowCount: 列表长度
             *    dataList: 列表数据
             *    rowRenderer: 渲染行元素的方法
             *    overscanRowCount: 用于沿用户滚动的方向呈现附加行
             *    deferredMeasurementCache: 用于临时呈现数据,缓存计算数据
             */
            <VirtualizedList
              width={this.state.viewWidth}
              height={this.state.viewHeight}
              rowHeight={this.cache.rowHeight}
              rowCount={dataList.length}
              rowRenderer={this.rowRenderer}
              deferredMeasurementCache={this.cache}
              dataList={dataList}
              overscanRowCount={1}
            />
          )} 
        </AutoSizer>
      </div>
    );
  }
}

export default Cp;

效果

相关推荐
wen's42 分钟前
React Native 0.79.4 中 [RCTView setColor:] 崩溃问题完整解决方案
javascript·react native·react.js
Jackson_Mseven7 小时前
面试官:useEffect 为什么总背刺?我:闭包、ref 和依赖数组的三角恋
前端·react.js·面试
前端小盆友9 小时前
从零实现一个GPT 【React + Express】--- 【2】实现对话流和停止生成
前端·gpt·react.js
OLong10 小时前
2025年最强React插件,支持大量快捷操作
前端·react.js·visual studio code
摸鱼仙人~10 小时前
重塑智能体决策路径:深入理解 ReAct 框架
前端·react.js·前端框架
namehu11 小时前
浏览器中的扫码枪:从需求到踩坑再到优雅解决
前端·react.js
杨进军11 小时前
React 使用 MessageChannel 实现异步更新
react.js
namehu11 小时前
浏览器中的打印魔法:Lodop与系统打印机
前端·react.js
如果'\'真能转义说11 小时前
React自学 基础一
前端·react.js·前端框架
巴巴_羊11 小时前
react setstate
react.js