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();
}, [])