【问题标题】:Using Map in React with firebase在 React 中使用 Map 和 firebase
【发布时间】:2018-08-06 03:55:53
【问题描述】:

请有人帮忙。我梳理了所有文档,检查了所有类似的问题,真的看不出我遗漏了什么。

我是新来的反应并试图映射从 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>
    );
}
}

我确信这是非常简单的事情,但我正在拔头发。如果我检查我的状态,我可以看到数据。控制台.log(this.state.data);在 renderPosts 内部甚至可以准确显示我需要映射的内容,但是映射回调中的所有内容都没有返回,我最终得到一个空的任何帮助将不胜感激。

【问题讨论】:

  • 我认为从 Firebase 获取数据是异步的,对吗?这意味着请求承诺的then 中的posts.push之后 setState 运行。
  • 相反,在 then 回调中设置凝视,而不是 forEaching 和 push,使用 map。通过将回调转换为箭头函数,确保使用正确的this
  • 是的,它是异步的。

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


【解决方案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");

当你运行它时,输出是:

开始获取文件之前

开始获取文件后

得到文件

这可能不是您预期的输出顺序。但这是预期的行为:在加载数据时不会阻塞代码(这会冻结浏览器),get().then() 块之后的代码会立即执行.然后当数据被加载时,代码inthen回调被执行。这就是为什么需要数据库中的文档的所有代码都需要在 then 回调中。

【讨论】:

  • 谢谢弗兰克 - 我很困惑为什么在上面的示例中,当我在 renderPosts() 中记录状态时,我有我需要的数据。如果我在 renderPosts() 中的 console.log 函数在您的解释中代替您的“开始获取文档后”运行,那么由于状态尚未更新,它不应该为空白吗?
  • 这很可能是 Chrome 如何记录对象的产物:它们是“实时的”而不是快照。尝试记录console.log(this.state.data.length);,我希望它仍然是0
  • 啊是的 - 它是 0
  • 感谢您的帮助,无法投票 b/c 我没有足够的积分 - 非常感谢您的帮助
  • @Li357 QuerySnapshot 没有map 方法:firebase.google.com/docs/reference/js/…
猜你喜欢
  • 2018-02-24
  • 1970-01-01
  • 2020-09-25
  • 1970-01-01
  • 2021-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-18
相关资源
最近更新 更多