Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Can't get onSnapshot to render once. It duplicates

i’m working on a project with React and Firestore.
I’m working on a page which will read through multiple images and certain fields of these images will be changed. Once changes are made, i just want the one image doc to update rather than everything on the page hence onSnapshot.
The onSnapshot listener keeps adding on to the images that i have whenever changes are made. I understand that everytime useEffect is called it adds the same images but i don’t know how to fix it. I have seen some solves here but they don’t cater to the IDs array which i need to reference a document when making changes to it.

export default function Images({ user }) {
  const [images, setImages] = useState([]);
  const [ids, setIDs] = useState([]);

  useEffect(() => {
    const colRef = collection(db, "images");
    const q = query(colRef, where("user", "==", user));

    onSnapshot(q, (snapshot) => {
      snapshot.docs.forEach((doc) => {
        setImages((prev) => [...prev, doc.data()]);
        setIDs((prev) => [...prev, doc.id]);
      });
    });
  }, [user]);

  return (
    <>
      {images && (
        <div className="m-4 grid grid-cols-2 grid-flow-row">
          {images.map((image, index) => {
            const imageID = ids[index];
            return <Labels image={image} imageID={imageID} />;
          })}
        </div>
      )}
    </>
  );
}

Any insights will be appreciated.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Have a look at the link you attached in your question: Why is onSnapshot duplicating my records in REACT? – The answer should be exactly what you want.

The issue here is that you’re using [...prev, doc.data()] no? This will cause the array to keep adding up everytime snapshot changes.
What you can do instead is to map through the snapshot.docs and then get the results and set it as your state as such:

  useEffect(() => {
    const colRef = collection(db, "images");
    const q = query(colRef, where("user", "==", user));

    onSnapshot(q, (snapshot) => {
      const docs = snapshot.docs;
      setIDs(docs.map(doc => doc.id);
      setImages(docs.map(doc => doc.data());
    });
  }, [user]);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading