如何乐观地更新ListView中的项目

Lea*_*cim 7 reactjs react-native

我正在制作一个简单的反应本机应用程序,它有几个列表,它使用户有机会更新任何列表中的项目或将新项目添加到列表中.

但是,正如之前在StackOverflow上指出的那样,无法将项添加或推送到ListView,因为它应该是一个不可变的数据结构.即在此代码中,无法将新项目推送到数据源中

var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var data = ds.cloneWithRows(responseData)
var obj = {};
obj['someproperty'] = 'foo';
data.push(obj); //cannot push a new item into data
Run Code Online (Sandbox Code Playgroud)

所以我所做的就是保留this.state.items;我从服务器获取的数据的副本(在下面的代码中)(我调用cloneWithRows它),附加到该副本(如果是编辑则更新它),然后调用cloneWithRows在任何时候有变化(通过编辑或创建新项目)并更新ui,然后更新服务器(最后一部分在反应原生应用程序范围之外)的变异副本上.所以总之,我有一个数据的副本,我可以变异以用作ds.cloneWithRows我进行更改时的数据来源

但是,listForUI: ds.cloneWithRows(t)如果我想要乐观地更新,保留数据结构的缓存似乎没有多大意义我可以改变它的唯一目的是将其用作不可变数据结构的源(在下面的代码中) UI(即在保存在服务器上之前显示更改).

替代方案(对我来说也没什么意义)似乎是更新服务器,并等待响应(不保留任何类型的缓存)任何时候我更新或添加新项目到我的列表,但这将慢吗?

问题:如果没有将数据的可变副本保存为缓存,是否有办法在反应原生中乐观地更新ui?

addNewItemToList: function(){

  var t = this.state.items;  //my cache of list items
  var newListItem = {};
  newListItem['id'] = 123;
  t.push(newListItem);  //adding-mutating the cache

  //creating a new immutable ds
  var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
  this.setState({
    listForUI: ds.cloneWithRows(t)
  }, function(){

     //update server with change
     fetch('http://localhost:8080/accounts/1/lists/3/todos', {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
        },
        //code ommitted
  }

 }
Run Code Online (Sandbox Code Playgroud)

Dav*_*ski 1

不,我很确定没有任何其他方法可以更新 ListView 数据源,因为正如您所解释的,它是不可变的。不变性意味着您始终需要在添加任何内容之前对其进行复制。

你提到:

然而,保留可以改变的数据结构的缓存似乎没有多大意义,其唯一目的是将其用作不可变数据结构的源......

我不太确定为什么您觉得保留此缓存没有意义。我也不认为它是导致性能问题的原因,因为缓存仅在addNewItemToList运行时存在很短一段时间。