在 React 中通过 firebase 使用 Map
2018-08-06
2980
请有人帮忙。我已梳理了所有文档,检查了所有类似的问题,但真的找不到我遗漏的内容。
我是 React 的新手,正在尝试映射从 Firebase 数据库的异步调用返回的文档。
这是代码:
class Posts extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
};
}
componentDidMount() {
let posts = [];
db.collection("Posts").get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
posts.push({
data: doc.data(),
id: doc.id
});
});
});
this.setState({
data: posts
});
}
renderPosts() {
console.log(this.state.data);
return this.state.data.map((post, index) => {
console.log(post);
console.log(index);
return (
<div>
{index}
</div>
)
})
}
render() {
return(
<div>
{this.renderPosts()}
</div>
);
}
}
我确信这是一件非常简单的事情,但我正在抓狂。如果我检查我的状态,我可以看到数据。console.log(this.state.data); 里面的 renderPosts 甚至准确显示了我需要映射的内容,但 map 回调中的所有内容都没有返回,我最终得到一个空的。任何帮助都将不胜感激。
1个回答
正如 Li357 所评论的,
setState
调用需要在
get()
回调内进行:
db.collection("Posts").get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
posts.push({
data: doc.data(),
id: doc.id
});
});
this.setState({
data: posts
});
});
这样做的原因是数据是从 Firestore 异步加载的,当您调用
setState
时,
posts
变量仍然为空。
理解这种异步加载的最简单方法是使用几行日志:
console.log("Before starting to get documents");
db.collection("Posts").get().then(function(querySnapshot) {
console.log("Got documents");
});
console.log("After starting to get documents");
运行此命令时,输出为:
Before starting to get documents
After starting to get documents
Got documents
这可能不是您预期输出的顺序。但这是预期的行为:不是在加载数据时阻止代码(这会冻结浏览器),而是立即执行
get().then()
块之后的代码。然后,当数据加载时,将执行
then
回调中的代码。这就是为什么所有需要从数据库获取文档的代码都需要位于
then
回调中的原因。
Frank van Puffelen
2018-08-06