React-native 和 Firebase ListView 集成

Posted

技术标签:

【中文标题】React-native 和 Firebase ListView 集成【英文标题】:React-native and Firebase ListView integration 【发布时间】: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>    
        );
    


【问题讨论】:

【参考方案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)
 *   );
 * 
 * ```
 */

【讨论】:

以上是关于React-native 和 Firebase ListView 集成的主要内容,如果未能解决你的问题,请参考以下文章

React-native 和 Firebase ListView 集成

我可以使用 React-native、firebase 和 node js 创建一个应用程序吗?

react-native ios项目中的Firebase身份验证问题

使用 react-native、Firebase 和 expo 的 signinwithemail 链接错误

用 react-native-firebase 编译 react-native

解析 Firebase 模块(React-Native)