'Can't update DOM by using useEffect and Firebase/Firestore
I got stuck on updating DOM, using useEffect and sending-getting data from Firebase. I work on a basic photo gallery website, that user selects a picture on local and send it Firebase/Firestore. All firebase actions work well. The main problem when I select image, it sends image immediately, but page doesn't update. When I manually update, then all images show up.
This is app.js file;
<div className='main'>
<Title />
<UploadForm />
<ImageGallery />
</div>
I upload image with UploadForm component then want to update DOM and add image to DOM immediately.
Here is my cumtom hook (useFirestore.js) file;
import { useState, useEffect } from 'react';
import { projectFirestore } from '../firebase/config';
import { query, orderBy, getDocs, collection } from 'firebase/firestore';
const useFirestore = (collectionName) => {
const [docs, setDocs] = useState([]);
useEffect(() => {
const getDocuments = async (collectionName) => {
const queryIt = query(
collection(projectFirestore, collectionName),
orderBy('createdAt', 'desc')
);
const querySnapshot = await getDocs(queryIt);
let documents = [];
querySnapshot.forEach((doc) => {
documents.push({ ...doc.data(), id: doc.id });
});
setDocs(documents);
};
getDocuments(collectionName);
}, [collectionName]);
return { docs };
};
export default useFirestore;
This docs object return to ImageGallery.js file which is:
const ImageGallery = () => {
const { docs } = useFirestore('images');
console.log('docs: ', docs);
return (
<div className={classes.gallery}>
{docs &&
docs.map((doc) => {
return (
<Card key={doc.id}>
<img src={doc.url} alt='Wallpaper Pictures' />
</Card>
);
})}
</div>
);
};
export default ImageGallery;
I tried many possibilities but I failed.
Solution 1:[1]
It might be because you are using getDocs instead of onSnapshot inside of your useFirestore hook.
You can read more about it in the Firebase documentation.
Solution 2:[2]
I post this message to help who struggle with the same problem. The real problem was using getDocs instead of onSnapshot as @Sandrow said. The code snippet that solve my problem is:
useEffect(() => {
const q = query(
collection(projectFirestore, collectionName),
orderBy('createdAt', 'desc')
);
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const documents = [];
querySnapshot.forEach((doc) => {
documents.push({ ...doc.data(), id: doc.id });
});
setDocs(documents);
});
return () => unsubscribe();
}, [collectionName]);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Sandrow |
| Solution 2 | mithderler |
