I have a React app built with the Minimal template and I’m trying to follow along with one of their tutorials, in order to create a Redux slice that feeds some data to a custom component. The data itself is collected from Firebase. Below is my code:
firebase.js – helper
export function getDocuments(col) { const colRef = collection(db, col); const q = query(colRef, where('uid', '==', auth.currentUser.uid)); getDocs(q).then((snap) => { const data = snap.docs.map((d) => ({ id: d.id, ...d.data() })); return data; }); // return [1,2,3] }
product.js – Redux slice
export function getProducts() { return async (dispatch) => { dispatch(slice.actions.startLoading()); try { const products = await getDocuments('products'); dispatch(slice.actions.getProductsSuccess(products)); } catch (error) { dispatch(slice.actions.hasError(error)); } }; }
ProductList.js – component
const dispatch = useDispatch(); const { products } = useSelector((state) => state.client); useEffect(() => { dispatch(getProducts()); }, [dispatch]); useEffect(() => { if (products.length) { // setTableData(products); } }, [products]);
If I console log data
in the helper function (firebase.js), I get the values I expect, once the promise is resolved/fulfilled. However, if I console.log clients
in the product.js slice or later in the component, I get undefined
.
I assume my problem is not being able to understand how async + await + useEffect work together in order to fix this. My assumption is that I am trying to access the value before the promise is resolved and therefore before the helper function returns it. I confirmed that by returning a simple array [1, 2, 3]
in my helper function as a test.
I think I am missing something fundamental here (I am not very experienced with React and JS in general and still learning things on the go). Can someone help me understand what am I doing wrong?
Thank you!
Advertisement
Answer
With await
you can await the fulfillment or rejection of a promise, but your getDocuments
Function does not return a promise. Change the last line of the function to the following:
return getDocs(q).then((snap) => { const data = snap.docs.map((d) => ({ id: d.id, ...d.data() })); return data; });