im trying to get a StoreKey from firestore (v9), and put it inside another collection of DB as a path. for example, get storeKey (132, for example) and put inside collection(db, 'store', storeKey, 'coffeeDB') to access specific sub collection. I put two function (1: getData (storeKey), 2: access to sub collection) into UseEffect, so that it can run when it's mounted. However, I found UseEffect runs twice, initial storeKey shows Array [], and next run gets proper value which is 132. So, im having an error due to the first run. I guess it's because the second function inside UseEffect does not wait getData function to watch the data, but not too sure. How can I resolve this issue??
const getData = async(setStoreKey, setName) => {
console.log('xxxx')
const auth = getAuth();
const user = auth.currentUser;
if(user !== null){
const email = user.email;
const UserInfo = await getDoc(doc(db, 'users', email));
if(UserInfo.exists()){
setStoreKey(UserInfo.data().storeKey)
setName(UserInfo.data().name);
}
else{
console.log('None')
}
return
}
}
T
const StockScreen = ({ navigation }) => {
const [storeKey, setStoreKey] = useState([]);
const [userName, setName] = useState([]);
const [coffeeStock, setCoffeeStock] = useState([]);
useEffect(() => {
getData(setStoreKey, setName);
const unsub = onSnapshot(collection(db, 'Store', storeKey, 'coffeeDB'), (snapshot) => {
setCoffeeStock(snapshot.docs.map((doc) => ({
id: doc.id,
data: doc.data(),
number: doc.data(),
})));
});
return unsub;
}, [storeKey]);
CodePudding user response:
Just remove dependency from second argument in useEffect
and pass blank array
useEffect(() => {
// your code
}, []);
It will run only once when your component is loaded. It is similar to componentDidMount
of class component.
CodePudding user response:
The reason your useEffect
run twice is because your storeKey
state changing in getData(setStoreKey, setName)
function. So what you can do here if you want to call getData()
function once is to declare it on a separate useEffect
function like:
useEffect(() => {
getData(setStoreKey, setName); //call your getData function once
}, []);
And what I see is you need to update StoreKey
every time for the unsub
listener so with that above useEffect
call another useEffect
whenever the StoreKey
dependency change like:
useEffect(() => {
getData(setStoreKey, setName); //call your getData function once
}, []);
useEffect(() => { //another useEffect whenever storeKey changes
const unsub = onSnapshot(collection(db, 'Store', storeKey, 'coffeeDB'), (snapshot) => {
setCoffeeStock(snapshot.docs.map((doc) => ({
id: doc.id,
data: doc.data(),
number: doc.data(),
})));
});
return unsub;
}, [storeKey]);
Hope this works for you.