i want to run the useEffect first before the render function which is placed inside the <Route />
tag starts to render. i expect to get currently available user details through the API and assigne them to render function.
but render function runs before the UseEffect retrieve data from the API. so help me to find the solution.
import React, { useEffect, useState } from "react";
import { Route, Redirect } from "react-router-dom";
import { Auth } from "aws-amplify";
const ProtectedRoute = ({ children, ...rest }) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
setIsAuthenticated(
Auth.currentAuthenticatedUser({
// bypassCache: false,
})
.then((user) => console.log(user))
.catch((err) => console.log(err))
);
}, []);
return (
<Route
{...rest}
render={({ location }) =>
(isAuthenticated ) ? (
children
) : (
<Redirect
to={{
// pathname: "/login",
pathname: "/create-profile",
state: { from: location },
}}
/>
)
}
/>
);
};
export default ProtectedRoute;
CodePudding user response:
Try this
useEffect(() => {
Auth.currentAuthenticatedUser({
// bypassCache: false,
})
.then((user) => user && setIsAuthenticated(true))
.catch((err) => err && setIsAuthenticated(false));
}, []);
CodePudding user response:
You could wrap that authentication stuff into a hook of your own, and then simply not render anything until it's ready:
function useIsAuthenticated() {
const [isAuthenticated, setIsAuthenticated] = useState(null);
useEffect(() => {
Auth.currentAuthenticatedUser({})
.then(setIsAuthenticated)
.catch((err) => {
console.log(err);
setIsAuthenticated(false);
});
}, []);
return isAuthenticated;
}
const ProtectedRoute = ({ children, ...rest }) => {
const isAuthenticated = useIsAuthenticated(); // Will be the user if authenticated, null if busy, or false if error.
if (isAuthenticated === null) {
return null; // Don't render anything if authentication state is unknown
}
return <>...</>;
};