RN ListView如何正确更新数据



  • 在已有的ListView的dataSource中插入一条新数据应该怎么做?
    我的做法是:

    var students = [];
    //result是服务端返回的JSON字符串,通过eval转化为对象
    students = eval(result);
    this.setState({dataSource: students});
    

    上面是初始化的数据可以正确加载,但是当我从服务端重新获得一条数据并插入到dataSource时,问题出现了:

    //在students的开头插入一条数据
    students.unshift(eval(result));
    this.setState({dataSource: students});
    

    上面的代码不会正确更新数据,而是在ListView的末尾增加了一条students插入前的最后一条数据,也就是说,ListView的最后两条数据是一样的,而预期是想在ListView的开头增加一条新数据。请问如何才能做到这一点?


  • administrators

    你需要深复制数组



  • @sunnylqm 具体如何操作?我也看了Immutable文档,但是具体不知道怎么用,求指导


  • administrators

    @KenChoi 你不用Immutable也可以啊,简单的深复制可以通过把你那个result重新JSON.parse(result)得到原先的那个基础数组的副本,然后去unshift增量数据。如果你没有保存原始result,那么把students先JSON.stringify再JSON.parse也可以实现简单的深复制效果。
    其实我比较好奇为啥你还在用古老的eval,fetch得到服务器数据的话,直接是能拿到json的(通过response => reponse.json()方法)



  • @sunnylqm 说:因为我是混合的React应用,在Native做了处理



  • @KenChoi 说:

    dataSource

    不要直接操作dataSource对象. 而应该对它赋予一个新的值.

    const students = this.state.dataSource, newStudent = eval(result)
    this.setState({dataSource: [newStudent, ...students]})
    


  • @kiliwalk 这样的话,如果我再插入一条新数据就会替换掉刚才插入的数据



  • @kiliwalk

    var students = [];
    
    getDataSource: function(students: Array<any>): ListView.DataSource {
        return this.state.dataSource.cloneWithRows(students);
    },
    
    var newStudent = eval(result);
    this.setState({dataSource: this.getDataSource([newStudent, ...students])});
    students = [newStudent, ...students];
    

    这样的话是可以的。。


登录后回复