Home > Back-end >  Including the missing useEffect dependency will create a loop
Including the missing useEffect dependency will create a loop

Time:04-23

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?

CodePudding user response:

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

CodePudding user response:

I would suggest checking out these two posts:

[Solved] How to fix missing dependency warning when using useEffect React Hook? React UseEffect and Unsubscribe promise with conditional listener ! (Optimize Firestore onsnapshot)

For your specific situation I would suggest separating out your onSnapshot call to firebase into a useCallback hook, it could look something like this:

const snapshotListener = useCallack(() => {
    const unsub = onSnapshot(q, (snapchat)=> {
       let documents = [];
       snapchat.forEach( (doc) => {
          documents.push({...doc.data(), id: doc.id})

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

useEffect( ()=> {
    // real time collection listiner
    snapshotListener();
}, [])
  • Related