虚拟列表无限下拉组件

import * as React from 'react';
import { debounce } from '@src/until/until';
export default class Scrool extends React.Component<any, any> {
    constructor(props: any) {
        super(props);
        this.state = { //eslint-disable-line
            cur: 0,
            itemHeight: props.itemHeight,
            size: Math.ceil(props.height / props.itemHeight),
            style: {

                height: props.height,
                overflow: 'auto',
                border: '1px solid gray',
                width: 300,

            },
            data: props.data
        };
    }
    list: any; // eslint-disable-line
    timer: any; // eslint-disable-line
    componentDidMount() {
        this.list.addEventListener('scroll', debounce(this.scroll, 500));
    }

    scroll=(e: any) => {
        // 这个监听事件干嘛呢  计算当前滑动到容器顶部的元素是第几个
        console.log('scroll');
        console.log(this.list.scrollTop);
        const index = Math.ceil(this.list.scrollTop / this.state.itemHeight);
        if (index > this.props.data.length - this.state.size) return; // cur会一直增加
        const updateCur = index;
        this.setState({ cur: updateCur });
    };
    getContent = () => {
        return <div style={this.getStyle()}>{this.renderList()}</div>;
    };
    renderList = () => {
        const { itemHeight } = this.props;
        const data =  this.handelData(this.props.data);
        const Lists = data.map((item: any, idx: number) => (
            <div key={item + idx} style={{ height: itemHeight, border: '1px solid red' }}>{item}</div>
        ));
        return Lists;
    };
    handelData = (data: Array<string>) => {
        const { size, cur } = this.state;
        const newData = [...data];
        if (data.length < size) return newData;
        let startIndex = cur;
        return newData.splice(startIndex, size);
    };
    getStyle = () => {
        const { cur, size, itemHeight, data } = this.state;
        let endIndex = cur + size;
        let paddingBottom =  itemHeight * (data.length - endIndex);
        let paddingTop =  cur * itemHeight;
        return {
            paddingTop: paddingTop,
            paddingBottom: paddingBottom,
        };

    };
    render() {
        return (
            <div ref={(ref: any) => this.list = ref} style={this.state.style}>
                {this.getContent()}
            </div>
        );
    }
}



  • 实现滚动到底部
var wrap = document.getElementById('wrap')
            wrap.scrollTop =wrap.scrollHeight;


  • 缓冲池

let socketPool = [];    //存储一段时间的数据
let socketTimer;
socketFun( (data) => {
  //先制造一个缓存区间,用来做缓存socket的数据
  socketPool.push(data);
  //每次都把当前的数据进行push到list
  if(!socketTimer){
    socketTimer = setTimeout(()=>{
      this.appendRecord(socketPool);
      socketPool.length = 0;
      this.scrollToBottom();
      socketTimer = null;
    },500);
  }
});



因为后端如果频繁传输数据,每次数据一来,就去更新页面,导致页面不管渲染更新,影响性能,通过缓冲池2s过后再将数据推进列表数据中,实现性能优化
核心就是减少渲染次数:
1s有10条数据,那么10s就要更新10次,如果2s更新一次,那么更新就变为5次,性能提升一倍

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值