我花了几天的时间试图弄清楚这一点,希望大家都能帮助我。我想从Cloud Firestore数据库获取帖子,并将其显示在React应用上。
我在Firestore中的数据的结构如下:
[项目] /新闻/ [文档]
每个文档在firestore中的结构如下:
[随机生成的ID]
- 标题:[string]
- body:[string]
我已经通过执行以下操作获取帖子:
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提取的对象数组上起作用?
预先感谢您的帮助!这让我很头疼。
答案 0 :(得分:0)
根据我对您问题的了解,我认为以下代码应该可以帮助您解决问题。
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>
);
}
}
此代码强调的要点是,反应是数据驱动的。本质上,您有一个称为发布的状态数组,您将在其上映射以呈现数据。当此数组为空时(例如在像初始渲染一样获取数据之前的情况),将不会渲染任何项目。一旦数据从数据库返回,数据就被添加到状态的posts数组中。调用setState
方法以强制执行新的渲染,但这一次我们要显示数据。
如果此回答表明我误解了您的问题,请进行后续操作。
希望这会有所帮助!
答案 1 :(得分:0)
我已经解决了!
我并不是一成不变地更改它。
这可以使其正常工作:
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 :(得分:0)
您对问题的答案仍然缺少右键。因此,对芒果问题的完整答案(以及自己的答案)将是:
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>
);
}
}