React结合虚拟列表VirtualList的动态获取列表项高度问题:

问题场景:页面查询大量数据的时候结合VirtualList也就是虚拟列表:
例如:手机通讯录查询联系人结合虚拟列表


问题描述:

大家如果不知道VirtualList这个组件,可以去官网看一下基本概念,这里是官网地址:连接.

具体的问题场景如下,大家如果用过这个插件应该就知道在List组件中rowHeight为一个必传项,因为他是用绝对定位加上你的列表项目高度和TOP等位置偏移属性值去控制你的滑动窗口当前显示的项目。


那么问题就来了,这个rowHeight属性代表着是你即将要渲染的列表项的行高,也就是rowRender属性里面的style,如果没细看的同学可能会有点懵圈,不过这也不难,直接上代码说明一下;

// <Listwidth={(window as any).visualViewport.width}height={listWrapHeight}rowCount={queryContactListHook.releasedNoticeSortByPinyinList.length}rowHeight={itemCompHeight.height}scrollToIndex={scrollToIndex}rowRenderer={({index,key,style}) => {return (<div key={key} style={{ ...style }}><div>list{index}</div></div>)}}/>

这里是用的TypeScript结合React,再用的List组件,list就是需要渲染的列表项数组,index是索引,从0开始, key是唯一标识,style就是css属性(PS:他会把自己的Style属性和你在组件上添加的style属性都传进去)

那现在已经问题很明显了,如果你要做的虚拟列表的列表项的高度是固定的,写死的,那这篇文章帮不了你什么,但是如果你写的列表项高度是动态变化的,那请你接着看下去。
我现在把虚拟列表的组件的高度写死,看会发生什么情况。

这里我把rowHeight属性写死成130

其实已经可以看到,因为在不同的设备上分辨率和宽高不同,你的列表项应该是动态变化,所以在设备分辨率不同的机子上这些列表项的排版方式会出现不同程度拥挤。


原因分析:

那么我们来分析一下原因,其实原因也很简单,因为你要渲染的列表项的高度不是写死的,他是随设备宽高变化而变化的,你把人家虚拟列表的列表项展示高度写死,自然只能适应一部分机型,而解决不了所有机型的问题;不仅如此,最棘手的问题就是你没办法单单通过改变的他列表项高度来解决rowHeight属性上的不足,所以如果想完全解决这个问题,还需要深思熟虑。


解决方案:

这个说起来可真不算容易,如果你的项目耦合度不大的话,组件化不完全,那么还有可能可以直接通过列表项的style解决问题,但是也只是有可能,反正我是没解决。。。

下面我给出我的几种解决思路:
1.把列表项的高度定死,从根源上解决问题,让问题不是问题,如果你的项目上不强制要求在不同的机型上列表项展示的高度等比例放大缩小,那么这个解决方案非常凑效;
2.获取列表项的高度,然后返回给List的rowHeight属性,如果你的列表项封装成了子组件,那么可以通过setState和props的回调函数解决这个问题,这个我试了一下,有问题;
3.给每个列表项都加上一个Ref,然后通过ref拿到他们的高度,再进行设置,这个解决方案不实际,忽略;
4. … …

我绞尽脑汁也想不出一个有效,不,别说有效了,就是能把bug解决的傻批方法都行,我翻阅了官网文档,看了下源码,发现都没有很好的解决方案,我冥思苦想,神情恍惚的在公司楼道里来回踱步,这不,终于让我想出了一个好点子!!!

首先,我们先分析一下,我们要动态计算高度,那么我们的任务就是要先拿到列表项的高度,但是你可能会疑问,之前的解决思路不就是这样吗?苦于逻辑原因,也就是在上面的方法中,之所以不凑效,是因为react先渲染列表属性,在他拿到了rowHeight属性的值和其他必须值之后,他才往下渲染对应的列表项,也就是list[index];换句话说,rowHeight当下需要的值正在未来,拿不到这个值,当然不能执行成功。
所以,我们改变下思考的方式,那我们只要能把这个未来的值拿到不就好了?
怎么拿到呢?
方法也很简单,我们来做一次假的渲染,什么是假渲染?首先你要理解React渲染HTML标签是从上往下渲染的,知道了这点之后我上代码你就知道怎么用的了;

<div className={state.first?"":"displayDiv"} ref={e=>setState({first:false,height:e.getBoundingReact().height})}>list[0]</div><Listwidth={(window as any).visualViewport.width}height={listWrapHeight}rowCount={queryContactListHook.releasedNoticeSortByPinyinList.length}rowHeight={state.height}scrollToIndex={scrollToIndex}rowRenderer={({index,key,style}) => {return (<div key={key} style={{ ...style }}><div>list{index}</div></div>)}}/>

怎么样,是不是恍然大悟,茅塞顿开,对于页面来说,他只是多加载了一条记录而已,本身不会造成多大负担,而对虚拟列表而言,他确实也拿到了每条列表项的动态高度(PS:这里的动态高度是指不同机型上宽高的等比例缩放,而不是内容本身的宽高随数据异同不同);

如果你要做的是根据数据量的异同列表项本身宽高不一致的动态高度,那么也不难,你在这个基础之上,计算出每一个列表项里面会赛多少小数据进去,每个小数据对应的高度如何,再全部累加起来,也能达到一样的效果,这个方法不是最好的,但是可以解决问题,如果你有更好的方法,欢迎留言评论介绍一下。

React结合虚拟列表VirtualList的动态获取列表项高度问题相关推荐

  1. Python入门--列表的查询操作--获取列表知道那个元素的索引、获取列表中的单个元素、获取列表中的多个元素

    #列表的查询操作 #获取列表中指定元素的索引 #index()-->如果列表中存在N个相同的元素,只返回相同元素中的第一个索引 # -->如果查询的元素在列表中不存在,则会抛出Valuee ...

  2. react入门-列表渲染(动态获取数据)

    注意:动态获取的是我自定义的后台数据,使用的时候请修改:componentDidMount中url 使用的数据如下: {"data": [{"author": ...

  3. 如何获取sharepoint列表_练习 34 - 获取列表元素 - Learn Python 3 The Hard Way

    练习 34 获取列表元素 列表(list)真的非常有用,前提是你要能获取到它们里面的内容.你已经能够按顺序遍历列表中的元素,但是如果你要取其中的第5个元素,你该怎么操操做?你需要知道如何获取一个列表里 ...

  4. python取列表中位数_Python如何获取列表(List)的中位数

    前言 中位数是一个可将数值集合划分为相等的上下两部分的一个数值.如果列表数据的个数是奇数,则列表中间那个数据就是列表数据的中位数:如果列表数据的个数是偶数,则列表中间那2个数据的算术平均值就是列表数据 ...

  5. js中动态获取页面的高度和宽度的方法总结

    javascript,jquery获取网页的高度和宽度: javascript: 可视区域宽:document.documentElement.clientWidth(width+padding) 可 ...

  6. 如何动态获取UILabel的高度、宽度

    用于自定义cell中每行内容不同时,获取行高 //这里width固定,就是动态获取行高CGSize fitLabelSize = CGSizeMake(320, MAXFLOAT);//height固 ...

  7. uniapp动态获取swiper的高度

    布局一下高度为动态的 <swiper class="swiper" :style="{height: windowHeight + 'px'}":curr ...

  8. ios动态获取UILabel的高度和宽度

    在使用UILabel存放字符串时,经常需要获取label的长宽数据,本文列出了部分常用的计算方法. 1.获取宽度,获取字符串不折行单行显示时所需要的长度 CGSize titleSize = [aSt ...

  9. uniapp 动态获取手机屏幕高度

    uniapp 动态获取屏幕高度再减去已有元素的高度等于剩下元素高度 uni.getSystemInfo({success: res => {this.screenHeight = (res.sc ...

最新文章

  1. pidstat 命令详解(转载)
  2. java大文件 索引_JAVA 大文件上传解决方案(500M以上)
  3. java joptionpane 例子_java JOptionPane类的介绍
  4. java更新 位置_请求位置信息更新  |  Android 开发者  |  Android Developers
  5. 只有mdf文件的恢复技术
  6. springboot2 虚拟路径设置_转载—springboot配置虚拟路径以外部访问
  7. SpringMVC拦截器-interceptor和filter区别
  8. NodeJs之数据库异常处理
  9. 箭头函数:this的指向问题
  10. Exception in Tkinter callback
  11. MOSS中删除绑定到List上的Eventhandler
  12. ROS学习记录:动作编程
  13. 历届美国梦之队战斗力汇总:梦一无敌 梦十二平淡
  14. Epson Perfection V370 Photo图片扫描自动控制
  15. python自学课堂_python自学——列表
  16. A/Btest:组间的差异性检验,统计功效以及反选样本量,附python底层实现代码
  17. 已解决:注册kaggle人机验证出不来
  18. 一篇文章,中文发完英文发,算“一稿多投”吗?
  19. GB2312与utf16、utf8的汉字对照表
  20. C语言递归算法——汉诺塔问题(河内塔)

热门文章

  1. 读书笔记-精准努力-走出第一步
  2. “漫画之家”系统毕设论文
  3. 精简版WIN10 LTSB LTSC安装Microsoft Store
  4. bzoj1085: [SCOI2005]骑士精神(a*)
  5. Oracle INTERVAL YEAR TO MONTH数据类型
  6. 除夕烟花python
  7. 计蒜客T1182 输出二进制补码(python3.6)
  8. okhttp3测试框架_OkHttp3系列(二)MockWebServer使用
  9. 游戏——TextOut函数
  10. 第16章-基于Hu不变矩的图像检索技术处理算法实现