在React和Firebase中使用Map

时间:2018-08-06 03:55:54

标签: javascript reactjs firebase google-cloud-firestore jsx

请有人帮忙。我已经整理了所有文档,检查了所有类似的问题,但实际上看不到我缺少的内容。

我是新来的反应者,尝试映射从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 个答案:

答案 0 :(得分: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异步加载数据,并且在您调用setStateposts变量仍然为空。

了解这种异步加载的最简单方法是使用几行日志:

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");

运行此命令时,输出为:

  

开始获取文档之前

     

开始获取文件后

     

获得的文件

这可能不是您期望输出的顺序。但这是期望的行为:get().then()块之后的代码不是在加载数据时阻止代码(这会冻结浏览器),立即执行。然后,在加载数据时,将执行then回调中的代码 in 。这就是所有需要数据库文档的代码都必须放在then回调中的原因。