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

Use Effect and Firebase causing infinite loop

I am using firebase and trying to load all my data at the start of the app using this code:

const [books, setBooks] = useState<BookType[]>([]);
const bookCollectionRef = collection(db, "books");

useEffect(() => {
  const getBooks = async () => {
    const data = await getDocs(bookCollectionRef);
    const temp: BookType[] = data.docs.map((doc) => {
      const book: BookType = {
        //set properties
      };
      return book;
    });
    setBooks(temp);
  };

  getBooks();
}, [bookCollectionRef]);

This useEffect is getting run constantly leading me to believe that I have made an infinite loop. I don’t see why this would be happening because I don’t think I am updating bookCollectionRef inside the useEffect hook. Is there possibly a problem where firebase collection references constantly get updated? Any ideas help!

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 :

From what I can tell it may be that collection(db, "books") returns a new collection reference each time the component rerenders. Any time the component renders (triggered by parent rerendering, props updating, or updating the local books state) the new bookCollectionRef reference triggers the useEffect hook callback and updates the books state, thus triggering a rerender. Rinse and repeat.

If you don’t need to reference the collection outside of the useEffect hook then simply omit bookCollectionRef and reference the collection directly. Trigger the useEffect only when the db value updates.

const [books, setBooks] = useState<BookType[]>([]);

useEffect(() => {
  const getBooks = async () => {
    const data = await getDocs(collection(db, "books"));
    const temp: BookType[] = data.docs.map((doc) => {
      const book: BookType = {
        //set properties
      };
      return book;
    });
    setBooks(temp);
  };

  getBooks();
}, [db]);

If you only need to run the effect once when the component mounts then remove all dependencies, i.e. use an empty dependency array.

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