Ben
Ben

Reputation: 3377

React useEffect inside async function

In react navigation (I could do this in App.ts too) I fire off the authentication like so:

export default function Navigation() {
  authenticateUser();
  ...
}

export default function authenticateUser() {
  const setLoadingUser = useStore((state) => state.setLoadingUser);

  firebase.auth().onAuthStateChanged(async (authenticatedUser) => {
    console.log('AuthenticateUser', authenticatedUser);
    setLoadingUser(false);
    if (authenticatedUser) {
      useAuthenticate(authenticatedUser);
    } else {
      console.log('No user');
      setLoadingUser(false);
    }
  });

  ...
}

And for the sake of simplicity, I will just print the user for now:

import { useEffect } from 'react';

export const useAuthenticate = (authenticatedUser) => {
  useEffect(() => {
    console.log('authenticatedUser', authenticatedUser);
  }, [authenticatedUser]);

  return true;
};

I believe that because I'm calling useAuthenticate inside the async firebase onAuthStateChanged function, React is throwing [Unhandled promise rejection: Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:]

How do I handle this?

Upvotes: 1

Views: 105

Answers (1)

Edmar Miyake
Edmar Miyake

Reputation: 12390

This should be:

export default function authenticateUser() {
  const {setAuthenticated} = useAuthenticate();
  const setLoadingUser = useStore((state) => state.setLoadingUser);

  firebase.auth().onAuthStateChanged(async (authenticatedUser) => {
    console.log('AuthenticateUser', authenticatedUser);
    setLoadingUser(false);
    if (authenticatedUser) {
      setAuthenticated(authenticatedUser);
    } else {
      console.log('No user');
      setLoadingUser(false);
    }
  });

  ...
}

import { useEffect, useState } from 'react';

export const useAuthenticate = () => {
  const [authenticated, setAuthenticated] = useState(false);

  useEffect(() => {
    console.log('authenticatedUser', authenticated);
  }, [authenticated]);

  return {authenticated, setAuthenticated};
};

Upvotes: 2

Related Questions