var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var dataSource = ds.cloneWithRows(['row 1', 'row 2']), };
但是,如果我想要从数据源中添加或删除项,我该怎么做?我需要始终使用更新后的数组调用cloneWithRows吗?
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var dataSource = ds.cloneWithRows(['row 1', 'row 2']), };
但是,如果我想要从数据源中添加或删除项,我该怎么做?我需要始终使用更新后的数组调用cloneWithRows吗?
cloneWithRows(...)
React Native文档没有涵盖ListViewDataSource
对象,因此阅读源代码中的注释可以帮助理解其工作原理。
以下是一些有用的注释:
cloneWithRows(data)
的名称有点误导性,因为它并不像名字所示的那样只是创建数据的副本。
相反,它会尝试将新的 data
行与数据源中现有行(如果有任何)进行比较,并确定是否有新行需要插入,或需要替换或删除的现有行。
源代码注释指出,设计上数据源中的数据是不可变的,因此更改它的正确方法是指定更新后的数据源,即调用cloneWithRows(...)
。
传递整个列表来更改几行可能看起来不直观,但有几个原因使它合理:
首先,这符合React的整体基于flux的架构,其中的重点是设置状态并允许组件自行确定如何变异以反映新状态(可以想象一下this.props
或this.state
的工作原理)。您可以在ListView
组件之外自由更改数据数组,但是一旦准备更新组件,则将整个状态传递给组件以使其自我更新是一个不错的flux方法。
其次,它的效率相当不错。ListView在渲染过程中会进行重量级的行差异处理,并在渲染周期中一次只呈现一行(您可以调整此内容),以减少帧率下降。
第三,这里没有排除未来支持像 .addRow(..)
这样的方法的可能性。关键是当前的实现并不是一个糟糕的开始,因为它提供了一个基于状态的接口,让开发人员不必担心列表组件在状态之间如何变化。
如果您查看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