skip to Main Content

I have build a custom hook:

const useFirestoreCollection = async (collectionName) => {

    const [documents, setDocuments] = useState([]);

    useEffect(() => {
        const fetchData = async () => {
            const querySnapshot = await getDocs(collection(db, collectionName));
            const documentsData = [];
            querySnapshot.forEach((doc) => {
                documentsData.push({
                    id: doc.id,
                    ...doc.data(),
                });
            });
            setDocuments(documentsData);
        };
        fetchData();
    }, []);

    return documents;
};

I can use it like this in my component:

const [myData, setMyData] = useState([]);

useFirestoreCollection('registeredUsers')
    .then((data) => {
        setMyData(data); // Data Access
    })
    .catch((error) => {
        console.log(error); // Error
    });

I could also delete the async in my custom hook:

const useFirestoreCollection = (collectionName) => { <- ASYNC DELETED
    const [documents, setDocuments] = useState([]);

    useEffect(() => {
        const fetchData = async () => {
            const querySnapshot = await getDocs(collection(db, collectionName));
            const documentsData = [];
            querySnapshot.forEach((doc) => {
                documentsData.push({
                    id: doc.id,
                    ...doc.data(),
                });
            });
            setDocuments(documentsData);
        };
        fetchData();
    }, []);
    return documents;
};

… and use it like this in my component:

const myData = useFirestoreCollection('registeredUsers')

I have tried to figure it out what is the best approach but was not able to do so.

When should I use the async keyword in my hook and when not?

2

Answers


  1. Making your hook async is useless in your first case as there’s nothing async going directly in your hook, only inside of your useEffect.

    That make it more difficult to use and makes you duplicate state.

    Login or Signup to reply.
  2. I have never seen a situation where a hook should be async. That hook returns a promise now, instead of simply the state & setState functions you want your component to use. This would be a major anti-pattern & complicate the simplicity of hooks terribly.

    If you ever need to use async/await functionality within a hook, you declare an async function within. Like you did.

    The second approach is clearly the right way to do this.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search