React实现虚拟滚动列表

原理: 只渲染可视节点以减少DOM开销,提升加载速度

以下代码是伪代码,具体实现看这

如果你想在项目中使用复杂的虚拟滚动,可以看下react-virtualized 。本文只提供虚拟列表实现思路

实现步骤

创建容器

<div className="container">
  <div className="virtual-container" />
</div>            

.container {
  height: 200px;
  width: 200px;
  border: 1px solid black;
  overflow-y: scroll;
}
.virtual-container {
  position: relative;
  overflow: hidden;
}

计算高度

通过每行高度乘以数据长度计算高度。这里是每行高度固定的情况,如果不固定可以参考实现中virtual-list-autoheight.js文件的实现(高度不固定,但一定要知道行的最大高度)

 const containerHeight = itemHeight * datasource.length;
 refVirtualContainer.current.style.height = containerHeight + "px";

 

实现滚动效果

因为我们只渲染一部分数据,无数据部分不能滚动,所以需要自己实现滚动。

我们利用transformY实现滚动效果

const refVirtualContainer = useRef();
const [scrollDis, setScrollDis] = useState(0);

useEffect(() => {
    refContainer.current.addEventListener("scroll", (e) => {
      setScrollDis(scrollTop);
    });
}, [])

<div className="virtual-container" ref={refVirtualContainer}>
 <div className="virtual"   style={{ transform: `translateY(${scrollDis}px)` }}/>
</div>   

 

更新数据

通过以上两步我们实现了可滚动的列表,之后需要在每次滚动时更新数据即可。

具体实现

const [dataSlice, setDataSlice] = useState([]); //数据切片   

refContainer.current.addEventListener("scroll", (e) => {
   setData(e.target.scrollTop, refContainerHeight, containerHeight);
});

const setData = (scrollTop, refContainerHeight, containerHeight) => {
    const beginNum = Math.ceil(
      (scrollTop / containerHeight) * datasource.length
    );
    const domNum = Math.ceil(refContainerHeight / itemHeight);
    setDataSlice(datasource.slice(beginNum, domNum * 2 + beginNum));
  };

   {dataSlice.map((item, idx) => (
    <div
      key={idx}
      className="item"
      ref={refItem}
      style={{ height: itemHeight, lineHeight: `${itemHeight}px` }}
    >
       <Button>{item * 80}</Button>
    </div>
  ))}

注意

  • 我们把key设置成idx,这样就能利用react机制使节点复用,减少性能消耗
setDataSlice(datasource.slice(beginNum, domNum * 2 + beginNum));
  • 这一段中 domNum * 2是为了在滚动时去掉闪烁,可以去掉试一下效果

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React-virtualized是一个非常流行的React库,它可以帮助我们实现大数据量的虚拟滚动效果。下面是一个使用React-virtualized实现虚拟滚动格的示例代码: 首先,我们需要安装React-virtualized库: ``` npm install react-virtualized --save ``` 然后,我们需要引入Table和Column组件: ``` import { Table, Column } from 'react-virtualized'; ``` 接下来,我们可以定义一个数据源,例如: ``` const list = [ { name: '张三', age: '18', address: '北京市海淀区' }, { name: '李四', age: '20', address: '北京市朝阳区' }, { name: '王五', age: '22', address: '北京市西城区' }, // ... // 这里可以添加更多的数据 ]; ``` 然后,我们可以定义一个Table组件,指定它的rowCount和rowGetter属性: ``` <Table rowCount={list.length} rowGetter={({ index }) => list[index]} > ``` 接下来,我们可以添加一些Column组件,定义每一列的属性: ``` <Column label="姓名" dataKey="name" width={100} /> <Column label="年龄" dataKey="age" width={100} /> <Column label="地址" dataKey="address" width={200} /> ``` 最后,我们需要在Table组件中添加一些属性,以启用虚拟滚动: ``` <Table rowCount={list.length} rowGetter={({ index }) => list[index]} headerHeight={20} rowHeight={30} width={600} height={400} > ``` 在上面的代码中,我们设置了headerHeight和rowHeight属性来指定头和每一行的高度,width和height属性用于指定格的宽度和高度。React-virtualized会自动根据这些属性来计算出需要渲染的行数,并且只渲染当前可见的行,以实现虚拟滚动的效果。 完整的代码示例: ``` import React, { Component } from 'react'; import { Table, Column } from 'react-virtualized'; const list = [ { name: '张三', age: '18', address: '北京市海淀区' }, { name: '李四', age: '20', address: '北京市朝阳区' }, { name: '王五', age: '22', address: '北京市西城区' }, // ... // 这里可以添加更多的数据 ]; class VirtualTable extends Component { render() { return ( <Table rowCount={list.length} rowGetter={({ index }) => list[index]} headerHeight={20} rowHeight={30} width={600} height={400} > <Column label="姓名" dataKey="name" width={100} /> <Column label="年龄" dataKey="age" width={100} /> <Column label="地址" dataKey="address" width={200} /> </Table> ); } } export default VirtualTable; ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值