我有一个名为user的类,其中包含用户类需要的所有方法和实例变量。在其中,我有一个方法负责将查询结果返回到index.js文件。在此index.js文件中,我希望使用查询中的值设置状态。但这不起作用。
function collectres () {
var store ='';
var docRef = db.collection("cities").doc("SF");
docRef.get()
.then(function (doc) {
if (doc.exists) {
console.log("Document data:", doc.data());
store = doc.data();// when referenced outside, it doesnt hold anything.
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
})
.catch(function (error) {
console.log("Error getting document:", error);
});
return store; // returns nothing and seems to not notice the assignment.
}
上面的函数在我的用户类中。从索引中引用时,它看起来像这样。
Random() {
let a = '';
a = user.collectres();
this.setState({name:a});
console.log(this.state.name);
}
但是这会将状态设置为先前的值。当我查看控制台日志时,我注意到,日志记录的顺序首先从index.js console.log(this.state.name)开始,但是我不应该首先收集res的日志。 任何帮助将不胜感激。
答案 0 :(得分:0)
从Firestore异步加载数据。数据加载期间,其余代码将继续执行,然后在数据存储在其中之后,将调用then
回调。
最容易通过一些放置正确的日志语句看到这一点:
console.log("Starting to load data");
docRef.get().then(function (doc) {
console.log("Got data");
});
console.log("Started to load data");
运行此命令时,它将打印:
开始加载数据
开始加载数据
获得数据
这可能不是您期望的输出,但是它完全解释了您所看到的行为。现在,您的return store
在store = doc.data()
之前运行 ,这说明了为什么无法获得所需的结果。
这意味着任何需要数据的代码都必须位于then()
回调中。因此,如果将通话移至setState()
之后的store = doc.data()
右边,它将可以正常工作:
docRef.get().then(function (doc) {
if (doc.exists) {
store = doc.data();
this.setState({name: store});
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
})
或者,您可以从then()
内向上返回该值。在这种情况下,您的通话代码中也需要then()
:
function collectres () {
var docRef = db.collection("cities").doc("SF");
return docRef.get()
.then(function (doc) {
if (doc.exists) {
return doc.data();
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
})
.catch(function (error) {
console.log("Error getting document:", error);
});
}
然后调用:
Random() {
let a = '';
user.collectres().then(function(a) {
this.setState({name:a});
});
}
异步API在现代编程中非常普遍,因此我强烈建议您阅读它们。有关更多信息,请参见: