I've been working on React/Redux app with firestore database
In my app I have simple POST request sent when the user send a message in the input field and the data the user enters supposed to render in the same page without the need to refresh but I do still need to refresh even without deps in my useEffect!
Here's my code :
- Post component
{posts.length > 0 &&
[...posts].map(({ id, data: { message, name, job, avatarUrl } }) => (
<Post
key={id}
name={name}
job={job}
message={message}
avatarUrl={avatarUrl}
/>
))}
However I also encounter a weird behavior after I refresh which is the components are rendered twice!Although my database be containing only one unique data for each messageThe react app renders it twice ( The querySnapshot from the database being added to the state arrayposts twice
- useEffect
useEffect(() => {
querySnapshot();
});
}, []);
Database query:
const q = query( collection(db, "posts"), where("type", "==", "post"), orderBy("postDate", "desc") );
Retrieving the data :
const [input, setInput] = useState("");
const [posts, setPosts] = useState([]);
const [nextId, setNextId] = useState("0");
const addPost = (e) => {
e.preventDefault();
const docData = {
name: "mo",
job: "zoo",
message: input,
avatarUrl: "https://",
postDate: firebase.firestore.FieldValue.serverTimestamp(),
type: "post",
};
setDoc(doc(db, "posts", nextId.toString()), docData);
setNextId(parseInt(nextId) 1);
setInput("");
};
async function querySnapshot() {
const querySnapshot = await getDocs(q);
console.log(querySnapshot.docs[0].data().message);
setNextId(querySnapshot.docs.length)
querySnapshot.docs.forEach((doc) => {
let data = {
id: doc.id,
data: doc.data(),
};
if (data && !posts.includes(data.id)) {
setPosts((current) => [...current, data]);
console.log("psts now", posts);
}
});
}
I tried to use the JavaScript Set by creating
useState(new Set())
but the same problem occurred of duplicate elements
I also tried to change deps of useEffect to render when the posts state array changes still not rendering untill I refresh
CodePudding user response:
The duplication reason would be caused by setPosts()
, I have updated the code as below, try to avoid setting the value inside the loop.
async function querySnapshot() {
const querySnapshot = await getDocs(q);
setNextId(querySnapshot.docs.length)
const data = querySnapshot.docs.map((doc)=>{
return {id:doc.id, data: doc.data()}
})
setPosts((current) => [...current, data])
}