渲染从 Firebase Firestore 映射的 React 组件
Posted
技术标签:
【中文标题】渲染从 Firebase Firestore 映射的 React 组件【英文标题】:Rendering React components mapped from Firebase Firestore 【发布时间】:2019-05-20 12:33:40 【问题描述】:我已经花了几天的时间试图解决这个问题,希望大家能帮助我。我想从 Cloud Firestore 数据库中获取帖子并将其显示在 React 应用上。
我在 Firestore 中的数据结构如下:
[项目]/NewsPosts/[文档]
每个文档在 Firestore 中的结构如下:
[随机生成的id]
标题:[字符串] 正文:[字符串]
我通过执行以下操作获得了帖子:
let posts= [];
//db = firebase.firestore();
db.collections.("NewsPosts").get().then((snapshot) => (
snapshot.forEach((doc) => (
posts.push(
id: doc.id,
title: doc.data().title,
body: doc.data().body
)
))
));
这成功地创建了一个包含我想要的信息的对象数组,因此获取数据不是问题。然而,当我去映射这个数组来创建帖子时,什么都没有被创建。我已经尝试了映射数组的所有变体来创建组件,但它不起作用。
但是,当我对一组对象进行硬编码并映射该对象时,它就可以工作了。例如,这适用于硬编码的对象数组:
//hard is the hardcoded array
let displayPosts = hard.map((p) => (
<div key=p.id>
<h1>p.title</h1>
<p>p.body</p>
</div>
))
return(
<Page>
displayPosts
</Page>
);
当我在浏览器控制台中比较硬编码数组和其他数组时,数组看起来不同。
我想是数组中的这种差异导致了问题。
如果有 2 个元素,这就是它们在浏览器控制台中的外观:
(2)[...,...] (hardcoded)
[] (array filled from firestore)
但是,关于数组的其他所有内容在浏览器控制台中都是相同的。
为什么这些数组看起来不同?这是让我无法正确映射每个索引处的对象的原因吗?如何让映射作用于从 Firestore 获取的对象数组?
提前感谢您的帮助!这让我很头疼。
【问题讨论】:
你能告诉鳕鱼在哪里尝试映射数组吗? 当然!我编辑了我的原始帖子以添加它 【参考方案1】:我已经解决了!
我并没有一成不变地改变它。
这使它正常工作:
constructor(props)
super(props);
this.state =
posts: []
componentDidMount = () =>
db.collection("NewsPosts").get().then((snapshot) => (
snapshot.forEach((doc) => (
this.setState((prevState) => (
posts: [...prevState.posts,
postID: doc.id,
title: doc.data().title,
body: doc.data().body,
featured: doc.data().featured
]
))
))
))
【讨论】:
我已经多次遇到这个问题,并不断回到这个答案。总是修复它!【参考方案2】:您对问题的回答仍然缺少正确的键。因此,Mango 问题的完整答案(以及自己的答案)将是:
class Sample extends React.Component
constructor(props)
super(props);
this.state =
posts: []
componentDidMount = () =>
db.collection("NewsPosts").get().then((snapshot) => (
snapshot.forEach((doc) => (
this.setState((prevState) => (
posts: [...prevState.posts,
postID: doc.id,
title: doc.data().title,
body: doc.data().body,
featured: doc.data().featured
]
))
))
))
render()
let displayPosts = this.state.posts.map((p) => (
<div key=p.postID>
<h1>p.title</h1>
<p>p.body</p>
</div>
))
return(
<Page>
displayPosts
</Page>
);
【讨论】:
【参考方案3】:根据我对您问题的理解,我认为以下代码应该可以帮助您解决问题。
class Sample extends React.Component
state =
posts: []
componentDidMount()
let posts = [];
db.collections.("NewsPosts").get().then((snapshot) => (
snapshot.forEach((doc) => (
posts.push(
id: doc.id,
title: doc.data().title,
body: doc.data().body
)
))
this.setState( posts )
));
render()
let displayPosts = this.state.posts.map((p) => (
<div key=p.id>
<h1>p.title</h1>
<p>p.body</p>
</div>
))
return(
<Page>
displayPosts
</Page>
);
这段代码强调的要点是,react 是数据驱动的。本质上,您有一个名为 posts 的状态数组,您将映射到该数组以呈现您的数据。当这个数组为空时,就像在初始渲染时获取数据之前的情况一样,不会渲染任何项目。一旦数据从数据库返回,数据就会添加到您的帖子数组中。调用setState
方法来强制进行新的渲染,但这次我们有数据要显示。
如果此答案表明我误解了您的问题,请继续跟进。
希望这会有所帮助!
【讨论】:
感谢您的回答!不幸的是,这不起作用。什么都没有显示。我不确定这些帖子是否会被添加到数组中,但我稍后必须对其进行测试。以上是关于渲染从 Firebase Firestore 映射的 React 组件的主要内容,如果未能解决你的问题,请参考以下文章
将 Firebase 身份验证用户映射到 Firestore 文档