I have a component that pulls in a subcollection from firestore:
import { useEffect, useState } from "react";
import { db } from '../firebase/firebaseInit'
import {useAuth} from '../components/AuthContextProvider'
import { collection, getDocs, setDoc, doc, addDoc } from "firebase/firestore";
type Inputs = {
name: string,
gender: string,
date: any,
}
function Subscriptions({ Component, pageProps }: any) {
const { user } = useAuth()
const [kids, setKids] = useState<any>([])
useEffect(() => {
const getKids = async (user: any) => {
if (user) {
const KidsCollectionRef = collection(doc(collection(db, "users"), user.uid), "kids")
const data = await getDocs(KidsCollectionRef)
setKids(data.docs.map((doc) => ({
...doc.data(), id: doc.id
})))
console.log(kids)
}
}
getKids(user)
}, [])
return (
<>
<h1>Welcome back</h1>
{/* need to loop throug the different prices */}
<div>
{kids.map((kid, index) => (
<span key={index} style={{display: 'block', width: '100%'}}>
{kid.name}
</span>
))}
</div>
</>
)
}
export default Subscriptions
But it only console.logs the data from kids
if I change useEffect
to this:
useEffect(() => {
const getKids = async (user: any) => {
if (user) {
const KidsCollectionRef = collection(doc(collection(db, "users"), user.uid), "kids")
const data = await getDocs(KidsCollectionRef)
setKids(data.docs.map((doc) => ({
...doc.data(), id: doc.id
})))
console.log(kids)
}
}
getKids(user)
}, [kids])
Which isn't ideal as it causes an infinite loop.
Here's the console.logs:
How do I make useEffect update when it gets the data from firestore?
CodePudding user response:
Just add user.uid
to useEffect dep, uid doesn't change, but it can be either undefined or a value, meaning it will trigger on value only
useEffect(() => {
const getKids = async () => {
if (user) {
const KidsCollectionRef = collection(doc(collection(db, "users"), user.uid), "kids")
const data = await getDocs(KidsCollectionRef)
setKids(data.docs.map((doc) => ({
...doc.data(), id: doc.id
})))
console.log(kids)
}
}
getKids()
}, [user?.uid])
CodePudding user response:
If you want to look at new kids, you can do so before the change state, in setKids.
useEffect(() => {
//...
setKids(() => {
const newState = data.docs.map((doc) => ({...doc.data(), id: doc.id}))
console.log(newState);
return newState;
})
}, [])
Or just add another useEffect
// useEffect with fetch
useEffect(() => { //... }, [])
// useEffect with log
useEffect(() => {
console.log(kids)
}, [kids])