Search code examples
google-cloud-firestorereact-hooksuse-effect

React useEffect hook running infinite loop despite static dependencies


Can someone please point to me what part of this code is causing an infinite loop? I have tried wrapping this in useCallback as well but it still runs forever.

  • slug is the page url that will not change over time
  • likesCollectionRef is also goint to remain constant
  • isAuth can change overtime depending on if the user is logged in or out
export default function CommentForm({ slug, isAuth, setReloadTS }) {
  const [isLiked, setIsLiked] = useState(false);

  const likesCollectionRef = collection(fireStore, 'likes');

  useEffect(() => {
    if (!isAuth) return;

    const qry = query(
      likesCollectionRef,
      where('slug', '==', slug),
      where('author.id', '==', auth.currentUser.uid)
    );

    const findLike = async () => {
      const data = await getDocs(qry);
      console.log(`initial like: ${data.docs}`);
      setIsLiked(data.docs !== 'undefined' && data.docs);
    };

    findLike();
  }, [slug, isAuth, likesCollectionRef]);
}

Solution

  • likesCollectionRef is declared each render cycle. Place the likes collection reference in a React ref so it's a stable reference. auth also appears to be an external dependency. If it's external to the component this is ok, but if it's internal to the component it should be added to the dependency array.

    export default function CommentForm({ slug, isAuth, setReloadTS }) {
      const [isLiked, setIsLiked] = useState(false);
    
      const likesCollectionRef = useref(collection(fireStore, 'likes'));
    
      useEffect(() => {
        if (!isAuth) return;
    
        const qry = query(
          likesCollectionRef.current,
          where('slug', '==', slug),
          where('author.id', '==', auth.currentUser.uid)
        );
    
        const findLike = async () => {
          const data = await getDocs(qry);
          console.log(`initial like: ${data.docs}`);
          setIsLiked(data.docs !== 'undefined' && data.docs);
        };
    
        findLike();
      }, [isAuth, likesCollectionRef, slug]);
    
      ...
    }