31

我们可以像这样为 ListView 创建一个数据源

var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});  
var dataSource =  ds.cloneWithRows(['row 1', 'row 2']), };

但是,如果我想从数据源中添加项目或删除项目,我该怎么做呢?我是否需要始终使用更新的数组调用 cloneWithRows?

4

2 回答 2

64

是的,打电话cloneWithRows(...)

React Native 文档没有涵盖该ListViewDataSource对象,因此阅读源代码中的注释以了解其工作原理会有所帮助。

一些可能有用的注释:

  • cloneWithRows(data)命名有点误导,因为不只是创建数据的克隆,正如其名称所暗示的那样。

  • 相反,它会尝试将新data行与数据源中的现有行(如果有)进行比较,并确定是否有要插入的新行,或者需要替换或删除的现有行。

  • 源代码注释说明数据源中的数据在设计上是不可变的,因此更改它的正确方法是指定更新的数据源,即调用cloneWithRows(...).

仅仅为了更改几行而传递整个列表可能看起来不直观,但有几个原因可以解释为什么它是有意义的:

  • 首先,它符合 React 的基于通量的整体架构,其中重点是设置状态并允许组件弄清楚如何改变自己以反映新状态(想想如何this.propsthis.state工作)。您可以随意更改ListView组件外部的数据数组,但是一旦您准备好更新组件,将整个状态传递给组件以便它可以自我更新是一种不错的通量方法。

  • 其次,它的效率相当高。ListView 在开始渲染过程之前在 Javascript 中进行重行区分,然后在渲染周期中一次渲染一行(您可以调整此项),以减少丢帧。

  • 第三,这里不排除支持类似.addRow(..)未来方法的可能性。关键是当前的实现并不是一个糟糕的开始,因为它提供了一个基于状态的接口,让开发人员不必担心列表组件如何在状态之间变化。

于 2015-10-08T00:05:52.033 回答
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

所以看起来你的方式是推荐的方法。

于 2015-03-30T17:16:12.640 回答