0

Using React and Firebase.

Created a custom hook that will get Firestore data from a collection, it works successfully but I get a warning.

Warning: 'React Hook useEffect has a missing dependency: 'q'. Either include it or remove the dependency array'

If I add 'q' as a dependency for the useEffect it will cause an infinite loop.

import { useState, useEffect } from "react";
import { collection, orderBy, query, getFirestore, onSnapshot } from "firebase/firestore";



const useFirestore = (coll) => {  
const [docs, setDocs] = useState([]);

//init services
const db = getFirestore();

//colletion ref
const colRef = collection(db, coll) 

// queries
const q = query(colRef, orderBy('createdAt', 'desc'))

useEffect( ()=> {
   


// real time collection listiner
const unsub = onSnapshot(q, (snapchat)=> {
    let documents = [];
    snapchat.forEach( (doc) => {
        documents.push({...doc.data(), id: doc.id})
 
    });
    setDocs(documents);
});

return () => unsub();

}, [])



  return {docs};
}

export default useFirestore

Is it okay to ignore it or am I using something incorrectly in my useEffect?

Jesse G
  • 31
  • 4
  • you can prevent the loop by moving the unsub outside the useEffect and calling it in the useEffect, and wrap your ```unsub``` function with a ```useCallback``` to maintain single instance between renders. This might answer your question https://stackoverflow.com/questions/53070970/infinite-loop-in-useeffect – Amr Apr 23 '22 at 05:07
  • Does this answer your question? [Infinite loop in useEffect](https://stackoverflow.com/questions/53070970/infinite-loop-in-useeffect) – Amr Apr 23 '22 at 05:07

1 Answers1

0

Just move setup functions inside useEffect since it will be executed only once.

import { useState, useEffect } from "react";
import { collection, orderBy, query, getFirestore, onSnapshot } from "firebase/firestore";

const useFirestore = (coll) => {  
  const [docs, setDocs] = useState([]);

  useEffect( ()=> {
     //init services 
    const db = getFirestore();

    //colletion ref
    const colRef = collection(db, coll) 

    // queries
    const q = query(colRef, orderBy('createdAt', 'desc'))

    // real time collection listiner
    const unsub = onSnapshot(q, (snapchat)=> {
        let documents = [];
        snapchat.forEach( (doc) => {
            documents.push({...doc.data(), id: doc.id})
        });
        setDocs(documents);
    });

    return () => unsub();
  }, [])

  return {docs};
}

export default useFirestore

bogdanoff
  • 1,705
  • 1
  • 10
  • 20