2015-08-29 61 views
3

我已經整合與之反應本土的火力地堡的一個問題。下面的代碼不會像我預期的那樣產生一個列表視圖。我的假設是,messages.val()不返回正確的格式。當我嘗試控制檯日誌「消息」變量返回如下陣營本地和火力地堡ListView控件集成

Object {text: "hello world", user_id: 1} 

代碼:

class Test extends Component { 

    constructor(props) { 
     super(props); 
     this.state = { 
      dataSource: new ListView.DataSource({ 
       rowHasChanged: (row1, row2) => row1 !== row2 
      }) 
     }; 
    } 

    componentWillMount() { 
     this.dataRef = new Firebase("https://dummy.firebaseio.com/"); 
     this.dataRef.on('child_added', function(snapshot){ 
      var messages = snapshot.val(); 
      this.setState({ 
       dataSource: this.state.dataSource.cloneWithRows(messages) 
      });  
     }.bind(this)); 
    } 

    renderRow(rowData, sectionID, rowID) { 
     console.log(this.state.dataSource); 
     return (
      <TouchableHighlight 
      underlayColor='#dddddd'> 
       <View> 
        <Text>{rowData.user_id}</Text> 
        <Text>{rowData.text}</Text> 
       </View> 
      </TouchableHighlight> 
     ) 
    } 

    render() { 
     return (
      <View> 
       <ListView 
        dataSource={this.state.dataSource} 
        renderRow={this.renderRow.bind(this)} 
        automaticallyAdjustContentInsets={false} /> 
      </View>  
     ); 
    } 

} 

回答

2

我不知道你有你的火力地堡數據庫中的哪些數據,但是從我個人理解,你應該讓你擁有所有項目的多條「on_child_added」事件,所以你不應該將它傳遞給「cloneWithRows」的方法。您應該將整個數據集傳遞給它。

儘管關於反應本機方面的文檔目前有點「沉默」,關於ListView數據源如何工作以及應該傳遞給「cloneWithRows」的代碼(ListViewDataSource.js)中的文檔實際上相當不錯,它是明確的,你應該總是提供完整的數據設置爲「cloneWithRows」的方法(類似於查看和解,數據源會自動計算出的差異,唯一的修改實際上已經改變了數據)。

此外,還有一個非常好的寫了由@vjeux爲什麼他們實施的ListView他們的方式,包括解釋他們選擇的優化策略(比iOS版的UITableView的不同)。

所以在你的情況下,你應該把所有的行累積到別的地方,只把整個消息傳遞給cloneWithRows或者繼承cloneWithRows的增量行爲,並且不斷地將傳入的元素追加到cloneWithRows中,就像下面的例子(它應該是快,所以給它一個嘗試)。

文檔副本&從ListViewDataSource.js貼:

/** 
* Provides efficient data processing and access to the 
* `ListView` component. A `ListViewDataSource` is created with functions for 
* extracting data from the input blob, and comparing elements (with default 
* implementations for convenience). The input blob can be as simple as an 
* array of strings, or an object with rows nested inside section objects. 
* 
* To update the data in the datasource, use `cloneWithRows` (or 
* `cloneWithRowsAndSections` if you care about sections). The data in the 
* data source is immutable, so you can't modify it directly. The clone methods 
* suck in the new data and compute a diff for each row so ListView knows 
* whether to re-render it or not. 
* 
* In this example, a component receives data in chunks, handled by 
* `_onDataArrived`, which concats the new data onto the old data and updates the 
* data source. We use `concat` to create a new array - mutating `this._data`, 
* e.g. with `this._data.push(newRowData)`, would be an error. `_rowHasChanged` 
* understands the shape of the row data and knows how to efficiently compare 
* it. 
* 
* ``` 
* getInitialState: function() { 
* var ds = new ListViewDataSource({rowHasChanged: this._rowHasChanged}); 
* return {ds}; 
* }, 
* _onDataArrived(newData) { 
* this._data = this._data.concat(newData); 
* this.setState({ 
*  ds: this.state.ds.cloneWithRows(this._data) 
* }); 
* } 
* ``` 
*/