Reputation: 147
I am stuck with a problem where I am building a blog with React and storing my blog posts in Firebase.
The problem is that it goes through all items correctly in the useeffect function but when I want to render my items on the page it only shows one, the last item in my array.
Here is my code:
export default function Blog(props){
const [blogPost, showBlogPost] = useState(null);
const [blogPosts, setBlogPosts] = useState([]);
useEffect(() => {
db.collection('blogposts').get().then(posts => {
console.log(posts.docs.length);
posts.docs.forEach(post => {
blogPosts.push(post.data());
console.log(post.data());
setBlogPosts([post.data()]);
console.log(blogPosts);
})
})
}, [])
console.log(blogPosts);
return(
<div>
{CreateBlogPost()}
{blogPosts.map(post => {
switch (blogPost) {
case post.id:
return( <BlogPost goBack={() => showBlogPost(null)} id={post.id} date={post.date} heading={post.heading} introduction={post.introduction} entry={post.entry} /> );
case null:
return(
<div>
<ul className="blog-posts">
<div className="blog-post-item" onClick={() => showBlogPost(post.id)}>
<img src={Image} alt="Girl in a jacket" width="400" height="200" />
<h1 id="blog-post-heading">{post.heading}</h1>
<div className="time-stamp">
<p id="blog-post-publish-date"><ClockIcon /> <time dateTime={post.date}>{post.date}</time></p>
</div>
</div>
</ul>
</div>
);
default: return null
}
})}
</div>
)
}
Here is where I console log my array after pushing all my data from Firebase in my array which works fine:
The code iterates through my code fine only within the useEffect function but when I console log blogPosts state array outside useEffect and try to render my array, it only renders the last item on the page.
Can someone please help me with this issue and guide me on how I should go forward here. All help is appreciated.
Thank you.
Upvotes: 0
Views: 1020
Reputation: 371069
Three problems:
.push
on stateful arrayssetBlogPosts([post.data()]);
only sets the new state array to a single itemsetBlogPosts
for every element in the array, when you should only be calling it once, after processing all posts.docs
Use
useEffect(() => {
db.collection('blogposts').get().then(posts => {
const newBlogPosts = [];
posts.docs.forEach(post => {
newBlogPosts.push(post.data());
})
setBlogPosts(newBlogPosts);
})
// .catch(handleErrors); // don't forget this part
}, [])
Upvotes: 4