最近开始用 RN 来写项目了, 记录一下今天使用 ListView 中的一个坑
引出这个问题的功能也很简单, 就是一个带有分页功能的 ListView , 然后我点击 ListView 其中的一个 cell , 就让这个 cell 的背景颜色改变(项目中的功能是单选or多选cell)
于是我先写了一个 ListView :
1 |
|
然后贴一下点击 cell 的方法:
1 |
|
这样 我以为点击了 cell 就能改变 这个 cell 的背景颜色了…但是事实却不是这样, 无论我怎么点击这个 cell, 他的背景颜色还是那样
于是我在google上搜了以下, 和我这种情况最相近的解决办法有两个, 一个是在点击 setState 时, 数据源不能和以前的相同, 于是我这么做了
1 |
|
这个办法然我比较奇怪的是, 我在不 setState dataSource 的时候居然是好用的, 就是点击哪一行那一行就改变了背景颜色, 但是紧接着问题又来了: 如果我进行了上拉加载操作, 那么再次点击, cell 的背景颜色就不会发生改变了, 上拉加载操作本质就是加载了更多数据, 然后放到 ListView.DataSource 里面更新 ListView, 由于改变外观与数据无关, 那我可以猜测问题是不是出在这句话上dataSource: this.state.dataSource.cloneWithRows(arr)
结果我看了一下他们的 ListView.DataSource 是这样写的
1 |
|
我抱着试一试的想法, 把我的 ListView.DataSource 也写成了这样, 居然达到了目标, 无论怎么刷新,点击哪一行, 那一行的背景颜色就改变了
那为什么这两个看起来一样的方法使用起来会有差别呢?
参考:这篇博客
他讲述了 this.state.dataSource.cloneWithRows(data)
与 自定义一个var ds = new ListView.DataSource({rowHasChanged: (r1, r2) =>{return r1 !== r2 }});
再 ds.cloneWithRows(data)
的区别, 观察区别的方法是这样的:
1 |
|
具体做法就是: 用以上不同的两个 ListView.DataSource 去充当 ListView 的 dataSource 然后在主页面上写两个按钮分别对应两种 ListView.DataSource, 当按钮点击的时候, 就去 cloneWithRows:
1 |
|
重复刷新几下app, 会发现ds.cloneWithRows(data)
这种方式会把数据直接放上去, 而this.state.dataSource.cloneWithRows(data2)
会比较刷新前后两种数据是否相同, 相同的话不会再次刷新这行 cell 不同的话才会刷新