如何在 ListView 中添加/删除项目?
Posted
技术标签:
【中文标题】如何在 ListView 中添加/删除项目?【英文标题】:How to add/Delete item into ListView? 【发布时间】:2015-03-30 16:20:04 【问题描述】:我们可以像这样为 ListView 创建一个数据源
var ds = new ListView.DataSource(rowHasChanged: (r1, r2) => r1 !== r2);
var dataSource = ds.cloneWithRows(['row 1', 'row 2']), ;
但是如果我想从数据源中添加项目或删除项目,我该怎么做呢?我是否需要始终使用更新的数组调用 cloneWithRows?
【问题讨论】:
【参考方案1】:是的,请致电cloneWithRows(...)
React Native 文档未涵盖 ListViewDataSource
对象,因此阅读 source code 中的 cmets 以了解其工作原理会有所帮助。
一些可能有用的注释:
cloneWithRows(data)
的命名有点误导,因为它不只是像名称所暗示的那样创建数据的克隆。
相反,它会尝试将新的data
行与数据源中的现有行(如果有)进行比较,并确定是否有要插入的新行,或者需要替换或删除的现有行。
源码cmets注意到数据源中的数据在设计上是不可变的,所以改变它的正确方法是指定一个更新的数据源,即调用cloneWithRows(...)
。
仅仅为了更改几行而传递整个列表可能看起来不直观,但有几个原因可以说明为什么这样做是有意义的:
首先,它与 React 的整体 flux-based architecture 一致,其中重点是设置状态并允许组件弄清楚如何改变自己以反映新状态(想想 this.props
或 this.state
的工作原理)。您可以在 ListView
组件之外随意更改数据数组,但是一旦您准备好更新组件,将整个状态传递给组件以便它可以自行更新是一种不错的通量方法。
其次,它的效率相当高。 ListView在开始渲染过程之前在 javascript 中进行大量的行区分,然后在渲染周期中一次渲染一行(您可以adjust this),以减少帧丢失。
第三,这里不排除将来支持像.addRow(..)
这样的方法的可能性。关键是当前的实现并不是一个糟糕的开始,因为它提供了一个基于状态的接口,让开发人员不必担心列表组件如何在状态之间变化。
【讨论】:
感谢您的解释!我对这个名字很困惑。您能否更具体地说明如何连续更新一些信息? 包含 10,000 行的列表怎么样?性能不会阻塞 UI 线程吗? 谁一次性滚动10000行?【参考方案2】:如果您查看 React Native 教程中扩展的电影示例,它实现了从远程 API 获取新电影的搜索。这意味着每次搜索都会刷新数据存储,从而有效地添加或删除项目。发生这种情况的确切位置在这里:
getDataSource: function(movies: Array<any>): ListView.DataSource
return this.state.dataSource.cloneWithRows(movies);
https://github.com/facebook/react-native/blob/master/Examples/Movies/SearchScreen.js#L209
所以看起来你的方法是推荐的方法。
【讨论】:
哦,是的..看起来这是唯一的方法!!..但是应该有一些方法..因为像这样我可能需要管理滚动位置等状态......跨度> 好点,但是您可以通过获取 ListView 的 ScrollView 滚动位置然后在数据存储更新后设置它来手动执行此操作。我同意这会有点笨拙,如果您可以自动执行此操作会更好。除非 RN 团队中的某个人可以给出更好的答案,否则我建议在 Github 跟踪器上打开一个问题 公平地说,即使在完全原生的 ios 上,这似乎也是一个手动过程:***.com/a/18855615/125680 现在它更有意义了..无论如何我更喜欢在此之上构建一个包装器,以便 RN 在这种功能上更加强大..我将在那里提出增强建议...让我们看看他们如何回应...以上是关于如何在 ListView 中添加/删除项目?的主要内容,如果未能解决你的问题,请参考以下文章