【问题标题】:React-native and Firebase ListView integrationReact-native 和 Firebase ListView 集成
【发布时间】:2015-08-29 07:55:57
【问题描述】:

我在将 Firebase 与 React-Native 集成时遇到了问题。下面的代码没有像我预期的那样生成列表视图。我的假设是 messages.val() 没有返回正确的格式。当我尝试控制台记录“消息”变量时,它返回如下

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>    
        );
    }

}

【问题讨论】:

    标签: javascript ios listview firebase react-native


    【解决方案1】:

    我不知道您的 Firebase 数据库中有哪些数据,但据我了解,您应该为您拥有的所有项目获取多个“on_child_added”事件,因此您不应将其传递给“cloneWithRows”方法。您应该将整个数据集传递给它。

    虽然 React Native 端的文档目前对于 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)
     *   });
     * }
     * ```
     */
    

    【讨论】:

      猜你喜欢
      • 2017-01-27
      • 2017-07-18
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-25
      • 2017-06-24
      • 1970-01-01
      相关资源
      最近更新 更多