清除DataSource时,React Native ListView不会更新

时间:2015-12-01 05:06:56

标签: android react-native

我更新组件的状态,如

if (!this.state.filtered) {
    this.setState({
        dataSource: this.state.dataSource.cloneWithRows(allData),
        filtered: false,
    });
} else {
    this.setState({
        dataSource: this.state.dataSource.cloneWithRows(filteredData),
        filtered: true,
    });
}

filteredData不为空时它工作正常。但是当filteredData是一个空数组时,ListView不会在setState(函数renderRow()rowHasChanged()之后也没有被调用)更新。)。
我试着打电话给listView.forceUpdate()但没用。 我的react-native版本是0.14.0并在Android 5.0上运行

===更新===
致电setState()后,使用console.log(this.state.dataSource)结果

{ 
  _rowHasChanged: [Function],
  _getRowData: [Function: defaultGetRowData],
  _sectionHeaderHasChanged: [Function],
  _getSectionHeaderData: [Function: defaultGetSectionHeaderData],
  _dataBlob: { s1: [] },
  _dirtyRows: [ [] ],
  _dirtySections: [ true ],
  _cachedRowCount: 0,
  rowIdentities: [ [] ],
  sectionIdentities: [ 's1' ] 
}

就我而言,变量allData的结构如下:

var allData = [[{id:1, name:'tom'},{id:2, name:'jerry'}], [...], [...]];  

filteredData只是一个空数组var filteredData = [];
我将filteredData修改为var filteredData = [[null]]并且listView可以正确呈现,不知道为什么,它只是有效:(

1 个答案:

答案 0 :(得分:0)

很难说清楚,因为我没有在您的代码中看到数据源(this.state.dataSource)的初始状态,但我认为问题可能是您需要设置数据源这样:

var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

比,调用这样的设置状态:

this.setState({
    filtered: true,
    dataSource: ds.cloneWithRows(filtereddata)
});

我已经设置了一个完整的工作项目here。此外,代码粘贴在下面。我希望这有帮助。

https://rnplay.org/apps/iPfYoQ

'use strict';

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

var alldata = [{name: 'chris'}, {name: 'jennifer'}, {name: 'james' }];
var filtereddata = []

var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

var SampleApp = React.createClass({

  getInitialState: function(){
    return {
      filtered: false,
      dataSource: ds.cloneWithRows(alldata)
    };
  },

  onPress: function() {
    if (!this.state.filtered) {
        this.setState({
            filtered: true,
            dataSource: ds.cloneWithRows(filtereddata)
        });
    } else {
        this.setState({
            filtered: false,
            dataSource: ds.cloneWithRows(alldata)
        });
    }
  },

  _renderRow: function(rowData) {
    return (
        <View>
            <Text style={styles.text}>
              {rowData.name}
            </Text>
        </View>
    );
  },

  checkFilter: function() {
    if (this.state.filtered) {
      return 'red';
    } else {
      return 'white'
    }
   },

  render: function() {
    return (
      <View style={styles.container}>
        <View>
                <TouchableHighlight 
      onPress={ () => this.onPress() }
      style={{flexDirection: 'row', alignContent: 'center', alignItems: 'center', height:70, backgroundColor: 'blue'}}>
                        <Text style={[{color: this.checkFilter(), fontSize:22, textAlign: 'center'}]}>Change Filter</Text>
                </TouchableHighlight>
      </View>
      <View style={{marginTop:10}}>
         <ListView 
           renderRow={this._renderRow}     
             dataSource={this.state.dataSource} />                         
      </View>

      </View>
    );
  }
});

var styles = StyleSheet.create({
  container: {
    flex:1
  },

});

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