我们可以像这样为
创建ListView的数据源var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var dataSource = ds.cloneWithRows(['row 1', 'row 2']), };
但是如果我想在数据源中添加项目或删除项目,我该怎么办呢?我是否需要始终使用更新的数组调用cloneWithRows?
答案 0 :(得分:64)
cloneWithRows(...)
React Native文档未涵盖ListViewDataSource
对象,因此阅读source code中的注释以了解其工作原理会很有帮助。
可能有用的一些注意事项:
cloneWithRows(data)
有点误导性命名,因为它不仅仅是像名称所暗示的那样创建数据的克隆。 相反,它尝试将新的data
行与dataSource中的现有行(如果有)进行比较,并确定是否要插入新行或需要的现有行替换或删除。
源代码注释注意到数据源中的数据是设计不可变的,因此更改它的正确方法是指定更新的数据源,即调用cloneWithRows(...)
。
传递整个列表只是为了改变几行似乎不太直观,但有几个理由说明为什么它有意义:
首先,它与React的整体flux-based architecture相符合,其中重点是设置状态并允许组件弄清楚如何改变自己以反映新状态(想想如何this.props
或this.state
有效)。您可以随意在ListView
组件之外更改数据数组,但是一旦准备好更新组件,就可以将整个状态传递给组件,这样它就可以自行更新。 / p>
其次,它效率很高。 ListView在开始渲染过程之前在Javascript 中执行繁重的行区分,然后在渲染周期中一次渲染一行(可以adjust this),以减少帧丢失
第三,这里没有任何内容可以排除将来支持.addRow(..)
等方法的可能性。关键是当前的实现并不是一个糟糕的开始,因为它提供了一个基于状态的接口,允许开发人员不必担心列表组件如何在状态之间发生变化。
答案 1 :(得分:8)
如果您查看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
所以看起来你的方式是推荐的方法。