React-native 和 Firebase ListView 集成
React-native and Firebase ListView integration
我在将 Firebase 与 React-Native 集成时遇到问题。下面的代码没有像我预期的那样生成列表视图。我的假设是 messages.val() 不是 return 正确的格式。当我尝试控制台日志 "messages" 变量时,它 returns 如下
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>
);
}
}
我不知道你的 Firebase 数据库中有什么数据,但据我了解,你应该为你拥有的所有项目获取多个 "on_child_added" 事件,所以你不应该将它传递给 "cloneWithRows" 方法。您应该将整个数据集传递给它。
虽然 React Native 方面的文档目前有点 "silent" 关于 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)
* });
* }
* ```
*/
我在将 Firebase 与 React-Native 集成时遇到问题。下面的代码没有像我预期的那样生成列表视图。我的假设是 messages.val() 不是 return 正确的格式。当我尝试控制台日志 "messages" 变量时,它 returns 如下
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>
);
}
}
我不知道你的 Firebase 数据库中有什么数据,但据我了解,你应该为你拥有的所有项目获取多个 "on_child_added" 事件,所以你不应该将它传递给 "cloneWithRows" 方法。您应该将整个数据集传递给它。
虽然 React Native 方面的文档目前有点 "silent" 关于 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)
* });
* }
* ```
*/