antd-mobile的长列表ListView不更新的坑

antd-mobile的长列表ListView在react hooks中不更新的坑

在react hooks中使用antd-mobile的长列表listView的时候,经常发现有时页面数据交互(如修改某行状态、点赞、评论等)后进行了更新,list和dataSource也更新了,但页面就是不更新;而上滑加载数据时list长度增加,dataSource随之更新,页面就能正常更新。感觉这应该是dataSource没有很好的识别更新条件而被驱动组件刷新,经反复探索,发现有时在dataSource更新的时候将list的内容通过JSON完全的复制一份就能解决,而有时list.slice()等方法复制数组也可以,下面罗列曾起作用的方法:

方法1

setDataSource(dataSource.cloneWithRows(JSON.parse(JSON.stringify(list) )))

方法2

后来网上还查到个方法 https://segmentfault.com/a/1190000022299102,在dataSource初始化时,修改rowHasChanged的值也可以,即

rowHasChanged: (row1, row2) => row1 !== row2

改为:

rowHasChanged: (row1, row2) => true,

这样牺牲了一定的性能,但需求实现了。

方法3

曾出现删除某条数据后页面又不更新的问题,后来把长列表的DataSource用slice()复制一份解决

const _dataSources = dataSources
_dataSources[activeTabIdx] = _dataSources[activeTabIdx].cloneWithRows(lists[activeTabIdx])
setDataSources(_dataSources.slice()) // 这样写删除某一条数据后才能及时更新

方法4

由于我这边是每个tab下各有一个长列表,发现某个tab下某个帖子点赞后,在另一个tab下的这个帖子却没有更新状态。点击tab时已经重新拉取了数据,经观察dataSources里面的内容都改了,列表状态就不刷新。后来用了非常手段解决——拉取数据时把这个DataSource初始化一下。这样牺牲了体验,每次点击都会有页面闪烁,不会复用之前的数据了。

if(initPage){
    setDataSources(dataSources.map(() => new ListView.DataSource({
        rowHasChanged: (row1, row2) => true,
    })))
}

方法5

问题

将list中每个条目改为多选功能后,发现上滑加载新的数据后多选失灵。经调试,发现每次点击后设置了当前选中的数据,但加载新的条目时,row取到的state已经被封存起来了不能改变,并非当前组件里的state,应该还是datasource的问题。尝试了上述各种更新DataSource的方法无果。后来发现initialListSize的数值设置比较大可以解决问题,但太大又会使页面变卡。

解决方案

最终做了前端分页(此接口无分页)配合initialListSize设置成动态值initialListSize={page * pageSize},完美解决了问题。

返回到长列表listView页面时白屏的问题(ISO)

当从长列表中某一条点击打开新的页面再返回后,在某个版本的IOS上出现了一个白色的大块堵住了列表内容,看起来就像白屏了一样。这时点击或稍微一触发滑动,白色块就消失,恢复正常。感觉这像是长列表的某个bug,后来用到的一个解决方案是:页面加载后让滚动条自动上移一个像素——这是一位美女前端提出的。

window.scroll(0,1);
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值