我们可以像这样为 ListView 创建一个数据源
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var dataSource = ds.cloneWithRows(['row 1', 'row 2']), };
但是,如果我想从数据源中添加项目或删除项目,我该怎么做呢?我是否需要始终使用更新的数组调用 cloneWithRows?
我们可以像这样为 ListView 创建一个数据源
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 的基于通量的整体架构,其中重点是设置状态并允许组件弄清楚如何改变自己以反映新状态(想想如何this.props
或this.state
工作)。您可以随意更改ListView
组件外部的数据数组,但是一旦您准备好更新组件,将整个状态传递给组件以便它可以自我更新是一种不错的通量方法。
其次,它的效率相当高。ListView 在开始渲染过程之前在 Javascript 中进行重行区分,然后在渲染周期中一次渲染一行(您可以调整此项),以减少丢帧。
第三,这里不排除支持类似.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
所以看起来你的方式是推荐的方法。