Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios react native:ListView,如何从顶部推送新行_Ios_React Native - Fatal编程技术网

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

Ios react native:ListView,如何从顶部推送新行,ios,react-native,Ios,React Native,我一直在努力理解如何制作一个能够接收新数据并将其推到前端的ListView。对于下面的代码,列表不能正确反映更改,最后一行将被复制,而不是在顶部有一个新行 'use strict'; var React = require('react-native'); var { AppRegistry, StyleSheet, Text, View, ListView, TouchableHighlight, } = React; var listview = React.cr

我一直在努力理解如何制作一个能够接收新数据并将其推到前端的ListView。对于下面的代码,列表不能正确反映更改,最后一行将被复制,而不是在顶部有一个新行

'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);
这确实有效,但我不明白为什么第一种方法不起作用。我试图找出处理ListView的最佳实践:

  • 在任何情况下,我都应该将cloneWithRows与新数组一起使用吗 对于单个添加/删除操作
  • 是否有其他设置使ListView/DataSource机制能够在最小重画(键,hasRowChanged)的情况下正常工作 具体比较

有点缺乏文件和例子,这将是伟大的澄清它为我和任何人。感谢您,祝您代码愉快。

ListView通过数据源索引分配组件键,因此,每当数据源预先添加到时,都将重新加载所有行。如果行数据具有唯一id,则可以创建一个修改的ListView,将其用作键。请参见示例,该示例将在行数据上使用id属性

注意:这个组件不是通用的,如果没有定义id属性,它将失败


注意:我意识到这并没有回答您的全部问题,只是关于预处理数据源的一个特殊问题。

好的,我知道已经对更改差异进行了参考检查,因此数组不能简单地进行变异。但是我仍然不知道列表如何在不破坏所有布局的情况下知道位置的变化,比如在前面添加新元素或删除现有元素。目前,行检查是基于它的数组索引的,当移动时,即使完全相同的元素只是下面的一行,它也会被视为完全不同的值,因此会重新绘制。这对性能来说是灾难性的:/这可能只为我节省了4或5个小时。非常感谢你!!!在我使用你的解决方案之前浪费了1小时。。。谢谢你,我也在寻找同样的解决方案。如果你有,请分享。
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),
    });
  },