Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to call async functions before the component renders in reactjs?

This is the private route component, and before users access the page I need to check if they are logged in (if their token is valid)

import { authService } from '../authservice/AuthService';

export default function PrivateRoute({ children }: { children: JSX.Element }) {
  //const isLoggedIn = authService.isLoggedIn();
  let location = useLocation();

  if (!isLoggedIn) {
    return <Navigate to="/login" state={{ from: location }} />;
  }
  return children;
}

This is the function I’m trying to call inside the PrivateRoute component

class AuthService {

    api_domain = "http://localhost:5000"

    async isLoggedIn() {

        if (!this.getToken() || typeof this.getToken() != 'string') {
            return false
        }

        axios.get(this.api_domain + "/", {headers: {Authorization: this.getToken()}})
        .then(res => {
            if (res.data.status === 'ok') {
                return true
            }
            return false
        })

    }
}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The reason the isLoggedIn function needs to be async is because it makes a request to your server, something which actually takes time. Therefore, what you want to be doing is displaying some sort of loading state until the user has been verified by the server.

You can create a custom hook which returns two states, isLoading and isLoggedIn, initializing isLoading as true:

export function useIsLoggedIn() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
        const token = getToken();
        if (!token || typeof token !== 'string') {
          setIsLoading(false);  
          return;
        }

        axios.get(api_domain + "/", {headers: {Authorization: token}})
        .then(res => {
            if (res.data.status === 'ok') {
                setIsLoggedIn(true);
            }
            setIsLoading(false);
        })
        .catch(() => setIsLoading(false));
  }, []);

  return { isLoggedIn, isLoading };
}

Then, in your PrivateRoute component, you can use this to ensure that the verification has already happened:

export default function PrivateRoute({ children }: { children: JSX.Element }) {
  const { isLoggedIn, isLoading } = useIsLoggedIn();
  const location = useLocation();

  if (isLoading) {
    return <div>Loading...</div>; // or some other loading state
  }

  if (!isLoggedIn) {
    return <Navigate to="/login" state={{ from: location }} />;
  }

  return children;
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading