简体   繁体   English

react-native:ListView,如何从顶部推送新行

[英]react-native: ListView, how to push new rows from top

I have been trying to understand how I could manage to make a ListView that can recieve often new data and push it to the front. 我一直试图了解如何设法制作一个可以接收新数据并将其推送到前面的ListView。 With the code below, the list does not reflect change correctly, instead of having a new row at the top, the last one is beeing duplicated.. 使用下面的代码,列表没有正确反映更改,而不是在顶部有一个新行,最后一个是重复的..

'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  ListView,
  TouchableHighlight,
} = React;

var listview = React.createClass({
  rows: [],

  _rowHasChanged: function (r1, r2) {
    // if (r1 !== r2)
    //   console.log('rowChanged', r1, r2);
    // else
    //   console.log('row didn\'t Changed', r1, r2);
    return r1 !== r2;
  },

  getInitialState: function() {
    return {
      dataSource: new ListView.DataSource({rowHasChanged: this._rowHasChanged}),
    };
  },

  componentDidMount: function () {
    this.rows = [
      {id: 0, text: '0: text'},
      {id: 1, text: '1: text'},
      {id: 2, text: '2: text'},
      {id: 3, text: '3: text'},
    ];

    this.setState({
      dataSource: this.state.dataSource.cloneWithRows(this.rows),
    });
  },

  pushTopRow: function () {
    var id = this.rows.length;
    this.rows.unshift({id: id, text: id + ': text'});

    this.setState({
      dataSource: this.state.dataSource.cloneWithRows(this.rows),
    });
  },

  render: function() {
    return (
      <View style={styles.container}>
        <ListView
          dataSource={this.state.dataSource}
          renderRow={(rowData) => <Text key={rowData.id}>{rowData.text}</Text>}
        />
        <TouchableHighlight
          onPress={this.pushTopRow}>
          <Text>PUSH TOP</Text>
        </TouchableHighlight>
      </View>
    );
  },
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'orange',
  },
});

AppRegistry.registerComponent('listview', () => listview);

then I tried: 然后我试过:

pushTopRow: function () {
    var id = this.rows.length;
    var newRow = [{id: id, text: id + ': text'}];
    this.rows = newRow.concat(this.rows);

    this.setState({
      dataSource: this.state.dataSource.cloneWithRows(this.rows),
    });
  },

this actually works, but I don't understand why first method doesn't work. 这实际上有效,但我不明白为什么第一种方法不起作用。 I'm trying to figure out what is the best practises for handling with ListView: 我试图找出使用ListView处理的最佳实践:

  • Am I supposed to use cloneWithRows with a new array in any case, even for a single add/delete operation ? 我是否应该在任何情况下使用带有新数组的cloneWithRows,即使是单个添加/删除操作?
  • Is there anything else to setup for the ListView/DataSource mechanics to works correctly with minimum redraw (keys, hasRowChanged specific comparision ?), 还有什么可以设置ListView / DataSource机制,以最小的重绘(键,hasRowChanged特定的比较?)正常工作,

kind of lacking of documentations and exemples, it would be great to clarify it for me and anyone. 有点缺乏文件和例子,为我和任何人澄清它会很棒。 thanks you & have a good code day. 谢谢你,并有一个很好的代码日。

ListView assigns component keys by data source index, and consequently will rerender all rows whenever the datasource is prepended to. ListView按数据源索引分配组件键,因此每当数据源被预先添加时,它将重新呈现所有行。 If your row data has any unique id, you can create a modified ListView that uses that as the key. 如果您的行数据具有任何唯一ID,则可以创建使用该行作为键的已修改ListView。 See for example PrependableListView which will use the id attribute on your row data. 请参阅例如PrependableListView ,它将在行数据上使用id属性。

Note: this component is not generalized and will fail if there is no id property defined. 注意:此组件不是通用的,如果没有定义id属性,则会失败。

Note: I realize this does not answer your whole question, just a specific peculularity about prepending to the datasource. 注意:我意识到这不能回答你的整个问题,只是一个关于前置数据源的具体特性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM