react-tiny-virtual-list 原理理解及简单实现

文章详细介绍了react-tiny-virtual-list插件的工作原理,它通过只渲染可视区域内的列表项来提高性能。在大量数据的列表渲染中,此插件能有效减少内存消耗和提升滚动流畅性。文中还给出了一个简单的自定义实现,模拟了插件的核心功能,包括监听滚动事件和动态渲染可见项。
摘要由CSDN通过智能技术生成

react-tiny-virtual-list 原理理解及简单实现

插件提供的API

  • width:整个列表的宽度
  • height:可视区域的宽度,即整个内容的高度
  • itemCount:数据列表的个数
  • itemSize:单项内容的高度
  • renderItem:渲染每一项内容

在渲染大批数据列表时可以使用改插件,实现原理是将在可视区域内渲染元素,在非可视区域内不渲染,但实际的占位高度存在。

import VirtualList from 'react-tiny-virtual-list'

const TestVirtualList = () => {
  let data = new Array(50).fill(0);
  let setProps = {
    width: '50%', //整个列表的宽度
    height: 500, //可视区域的宽度,即整个内容的高度
    itemCount: data.length, //数据列表的个数
    itemSize: 50, //单项内容的高度
    renderItem: (data) => {
      //渲染每一项内容
      const { index, style } = data;
      return (
        <div key={index} style={{ ...style, backgroundColor: index % 2 === 1 ? 'red' : 'yellow' }}>
          {index + 1}
        </div>
      );
    },
  };
  return (
    <div>
      <VirtualList {...setProps} />
    </div>
  );
};

简单实现 react-tiny-virtual-list类似原理的方式

import React, { useRef, useState } from 'react';

const VirtualList = (props) => {
  const { height, width, itemCount, itemSize, renderItem } = props;
  const scrollBoxRef = useRef(null);
  const [start, setStart] = useState(0);
  const handleScroll = () => {
    const { scrollTop } = scrollBoxRef.current;
    const newStart = Math.floor(scrollTop / itemSize);
    setStart(newStart);
  };
  let end = start + Math.floor(height / itemSize) + 1; //11
  end = end > itemCount ? itemCount : end; //如果结束的索引已经越界了,到结束为止
  //visibleList=[findex:0],.....(index:10}]
  const visibleList = new Array(end - start)
    .fill(0)
    .map((item, index) => ({ index: start + index }));
  let itemStyle = { position: 'absolute', left: 0, width: '100%', height: 50 };
  return (
    <div
      style={{ overflow: 'auto', willChange: 'transform', height, width }}
      ref={scrollBoxRef}
      onScroll={handleScroll}
    >
      <div style={{ position: 'relative', width: '100%', height: `${itemCount*itemSize}px` }}>
        {visibleList.map(({ index }) =>
          renderItem({ index, style: { ...itemStyle, top: itemSize * index } }),
        )}
      </div>
    </div>
  );
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值