'Best practices for async await when retrieving data from firestore

I had this error before

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

This is my useEffect where I retrieve data from firestore and it does remove the error:

 useEffect(async () => {
    let isMounted = true;
    const querySnapshot = await getDocs(collection(db, "product"));
    const arr = [];
    querySnapshot.forEach((doc) => {
      arr.push({
        ...doc.data(),
        id: doc.id,
      });
      if (isMounted) setProduct(arr);
    });
    return () => {
      isMounted = false;
    };
  }, []);

Is the useEffect alright or will this cause any problems in the future? And am I mounting this right?



Solution 1:[1]

Ths look okay. But it's best to extract the fetching logic into a separate function instead of having the entire logic in the body of the useEffect. It gets easy to re-use the logic for functionality like retrying if the request failed on mount.

I would do something like this...

  • Note: I removed the isMounted as the effect with be run when the component is mounted.
  • Wrap the function in an async function(named or anonymous) inside the useEffect and run it immediately.
// Re-usable logic for stuff like reload/retry
const fetchProduct = async () => {
  const querySnapshot = await getDocs(collection(db, "product"));
  const arr = [];
  querySnapshot.forEach((doc) => {
    arr.push({
      ...doc.data(),
      id: doc.id,
    });
  });
  setProduct(arr); // Moved this out of the loop to be run once.
}

useEffect(async () => {
  (async () => {
    await fetchProduct();
    // await other async operations here.
  })(); // This immediately runs the func async.
}, []);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 iamcastelli