I am trying to read the data from a Firebase Firestore collection called 'posts'. Its having few documents in it. When I am using the following code to read data, I am able to read it but two times:
- code in posts.jsx file:
import React, { useEffect, useState } from "react";
import '../index.css';
import '../../node_modules/antd/dist/antd.min.css';
import PostSnippet from './PostSnippet';
import _ from 'lodash';
import { PageHeader } from "antd";
import { db } from '../firebase.js';
import { collection, getDocs } from "firebase/firestore";
function Posts(props) {
const [posts, setPosts] = useState([]);
useEffect(() => {
const fetchData = async () => {
const postRef = collection(db, 'posts');
const postSnap = await getDocs(postRef);
postSnap.forEach(doc => {
let data = doc.data()
let { id } = doc
let payload = {
id,
...data,
}
setPosts((posts) => [...posts, payload])
})
}
fetchData()
.catch(console.error);
}, [])
return (
<div className="posts_container">
<div className="page_header_container">
<PageHeader
style={{
border: '5px solid rgb(235, 237, 240)',
fontSize: '25px',
margin: '40px',
}}
title="Post"
/>
</div>
<div className="articles_container">
{
_.map(posts, (article, idx) => {
return (
<PostSnippet
key={idx}
id={article.id}
title={article.title}
content={article.content.substring(1, 300)} />
)
})
}
</div>
</div>
)
}
export default Posts;
- Code in PostSnippet.jsx file which is used to give the view to individual cards:
import React from "react";
import { Card } from "antd";
import { Link } from "react-router-dom";
const PostSnippet = (props) => {
return (
<>
<div className="post_snippet_container" style={{ margin: "40px" }}>
<Card
type="inner"
title={props.title}
extra={
<Link to={`/post/${props.id}`}>
Refer the Article
</Link>}
>
<p className="article_content">
{
props.content.split('\n').map((paragraph, idx) => {
return <p key={idx}>{paragraph}</p>
})
}
</p>
</Card>
</div>
</>
)
}
export default PostSnippet;
CodePudding user response:
setPosts((posts) => [...posts, payload])
You only ever add to the array, so when data is fetched for the second time, you grow your array to twice the size. Instead, replace the array with the new data. That way the second fetch will overwrite the first:
const fetchData = async () => {
const postRef = collection(db, 'posts');
const postSnap = await getDocs(postRef);
const newPosts = postSnap.docs.map(doc => {
return {
id: doc.id,
...doc.data(),
}
});
setPosts(newPosts);
}