【问题标题】:React Native ListView not updating when cleared DataSource清除 DataSource 时 React Native ListView 不更新
【发布时间】:2015-12-01 05:06:55
【问题描述】:

我像更新组件的状态

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可以正确渲染,不知道为什么,正常工作:(

【问题讨论】:

  • clonewithRows 将始终将输入作为数组,因此请确保将 dataSource 本身分配为 null 或空数组到 clonewithrows

标签: android react-native


【解决方案1】:

很难准确判断,因为我在您的代码中没有看到您的数据源 (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);

【讨论】:

  • 感谢您的回答和样品!我更新了我的问题,您还有其他建议吗?再次感谢。
猜你喜欢
  • 2016-03-09
  • 1970-01-01
  • 2016-01-30
  • 1970-01-01
  • 2017-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-28
相关资源
最近更新 更多