【问题标题】:Using React + Firebase, how to modify state inside a nested query?使用 React + Firebase,如何修改嵌套查询中的状态?
【发布时间】:2017-02-27 11:39:49
【问题描述】:

我目前这样初始化我的状态:

getInitialState: function () {
    return {
        conversations: {},
        messages: {},
        availableConversations: {}
    }
},

如果我这样做:

convosRef.on('value', snapshot => {
        this.setState({ conversations: snapshot.val() });
    });

它可以按需要工作......但是:

users: {
    uid: {
        conversations: {
            conversationid: true,
            conversationid2: true
        }
    }
}

我成功拿到了想要的对象:

userSnapshot.child('conversations').forEach(function (conversationKey) {
            var conversationRef = database.ref('conversations').child(conversationKey.key);
            conversationRef.on('value', function (conversationsSnapshot) {
                var conversation = conversationsSnapshot.val();
                conversationLoadedCount = conversationLoadedCount + 1;
                myObject[conversationKey.key] = conversation;
                // console.log(conversationKey.key);
                //this.state.conversations = conversation;

                if (conversationLoadedCount === conversationCount) {
                    console.log("We've loaded all conversations");

                }
            });
            this.setState({ conversations: myObject });
        });
    });

但是。我收到两个错误,但我无法影响状态: 第一个错误: `FIREBASE 警告:用户回调引发了异常。类型错误:无法读取 null 的属性“setState”

还有一点类似: Uncaught TypeError: Cannot read property 'setState' of null

我的代码基于这个出色的答案,但没有任何成功: Firebase two-way relationships / Retrieving data

这是在 componentDidMount function 内部运行的。

关于如何影响状态的任何建议?

【问题讨论】:

  • 我找到了解决问题的方法。只需在每次 firebase 调用后添加“.bind(this)”就可以了。我不想将其标记为答案,因为我可以使用一些关于性能的建议:)

标签: javascript reactjs firebase firebase-realtime-database


【解决方案1】:

在 ES6 中,如果你使用胖箭头函数,这会更简洁,并且会绑定“this”,例如:

   userSnapshot.child('conversations').forEach((conversationKey) => {
            var conversationRef = database.ref('conversations').child(conversationKey.key);
            conversationRef.on('value', (conversationsSnapshot) => {

【讨论】:

【解决方案2】:

我只是通过尝试绑定它找到了解决我的问题的方法。 解决方案是在我拨打firebase.database().ref() 时使用bind(this)。 这是最终的sn-p,希望它可以帮助像我这样的可怜的灵魂,如果有人有更好的答案或有关如何改进它的一些解释,请告诉我:

var myObject = {}; usersRef.on('value', function (userSnapshot) {

        // First we get the qty of conversations.
        var conversationCount = userSnapshot.child('conversations').numChildren();
        // we initialize an empty counter
        var conversationLoadedCount = 0;
        // we traverse now the conversations ref with the past conversations.
        userSnapshot.child('conversations').forEach(function (conversationKey) {
            var conversationRef = database.ref('conversations').child(conversationKey.key);
            conversationRef.on('value', function (conversationsSnapshot) {
                var conversation = conversationsSnapshot.val();

                conversationLoadedCount = conversationLoadedCount + 1;
                myObject[conversationKey.key] = conversation;
                // console.log(conversationKey.key);
                this.state.conversations[conversationKey.key] = conversation;
                this.setState({ conversations: this.state.conversations });
                if (conversationLoadedCount === conversationCount) {
                    console.log("We've loaded all conversations");
                }
            }.bind(this)); // one for the usersRef
        }.bind(this)); // another one for the forEach inside 
    }.bind(this)); // the final one for the conversationRef.on...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    相关资源
    最近更新 更多