我在我的代码中使用了两个链式firebase请求。第一个是获取所有评论,然后我迭代所有结果,为循环中的每个元素发出第二个firebase请求。
在循环之后,我使用state
使用新数据更新了setState
。而且这个更新使我的GUI变得透明,如下所示:
底部每次都是随机透明的,有时渲染可见一点,有时根本不可见。当我删除setState
块时,一切都很好。
有问题的代码:
getReviews() {
let reviewData = {}
let vendorId = this.props.item.vendor_id
let product = this.props.item.key
firebase.database().ref('u_products/' + vendorId + '/' + product + '/reviews/').once('value', (data) => {
reviewData = data.val()
if (!reviewData) {
this.setState({
loadedReviews: true
})
return
} else {
for (var key in reviewData) {
firebase.database().ref('users/' + reviewData[key].poster_uid + '/').once('value', (data) => {
let userData = data.val()
if (userData) {
this.getUserImageUrl()
...
}
})
}
this.state.reviewData = reviewData
this.setState({
dataSource: this.state.dataSource.cloneWithRows(reviewData),
loadedReviews: true,
})
}
})
}
预期行为是第一个firebase请求 - >第二个迭代第一个请求的所有结果 - > setState。
还有其他人有这个问题吗?
答案 0 :(得分:1)
firebase' .once()
返回Promise
,因此您需要创建一个Promise数组,然后调用Promise.all(array).then((arrayOfData) => { ... });
您现在可以处理生成的数组,然后调用.setState()
这是一个模型:
/* firebase mockup */
function Result(url) {
this.url = url;
this.once = function(param, callback) {
return new Promise((resolve, reject) => {
setTimeout(() => {
var data = {
val: () => {
return this.url + " query result";
}
};
resolve(data);
}, Math.random() * 500 + 1000);
});
};
}
var firebase = {
database: function() {
return firebase;
},
ref: function(url) {
return new Result(url);
}
};
var reviewData = {
"test": {
poster_uid: "testData"
},
"2nd": {
poster_uid: "2ndData"
}
};
// ACTUAL IMPORTANT CODE BELOW #################
var arrayOfPromises = [];
for (var key in reviewData) {
arrayOfPromises.push(firebase.database().ref('users/' + reviewData[key].poster_uid + '/').once('value'));
}
Promise.all(arrayOfPromises).then(function(arrayOfResults) {
arrayOfResults.map((data, i) => {
let userData = data.val();
if (userData) {
console.log(i, userData);
}
});
console.log("setting state now");
});