hi i'm doing protected routes using react router v6 it is redirecting fine but let's say i'm in /login and i'm not authenticated and i want to go to /dashboard here /dashboard will be rendered for some few miliseconds (i can see it ) then i will be redirected to /login how can i prevent that rendering. here's my code :
import { useEffect, useState } from "react";
import { Route, useNavigate } from "react-router-dom";
import { Auth } from "aws-amplify";
const protectedRoute = (Comp, route = "/login") => (props) => {
const navigate = useNavigate();
const checkAuthState = async () => {
try {
await Auth.currentAuthenticatedUser();
console.log("React Router user authenticated ");
} catch (err) {
console.log("React Router we have an error");
navigate(route);
}
};
useEffect(() => {
checkAuthState();
});
return <Comp {...props} />;
};
export default protectedRoute;
this is how i ordered my routes in App.js
<Router>
<Routes>
<Route path="/" element={<Navigate to="/login" replace={true} />} />
<Route path="/login" element={<Login />} />
<Route path="dashboard/*" element={<Dashboard />} />
<Route path="/signup" element={<Signup />} />
<Route path="RecoverPassword" element={<RecoverPassword />} />
<Route path="resetPassword" element={<ResetPassword />} />
<Route path="verifycode" element={<VerifyCode />} />
<Route path="policy" element={<>this is policy</>} />
</Routes>
</Router>
You can create a flag to tell if the checking is don or not, while that you can show some loader to the user instead of the component.
onst protectedRoute = (Comp, route = "/login") => (props) => {
const navigate = useNavigate();
const loading = useState(false);
const checkAuthState = async () => {
// start checking, show loader
setLoading(true)
try {
await Auth.currentAuthenticatedUser();
console.log("React Router user authenticated ");
} catch (err) {
console.log("React Router we have an error");
navigate(route);
}
// end checking, hide loader
setLoading(false)
};
useEffect(() => {
checkAuthState();
}, []);
if(loading) {
return "loading..."
}
return <Comp {...props} />;
};
i got it you know what was happening is that useEffect will be executed when my component mounts (i returned redirection component so it will be rendered ) what i did is putting my component into a state initialized to empty <></> then when my protected route mounts i change the state to what i want to render
import { useEffect, useState } from "react";
import { Route, useNavigate } from "react-router-dom";
import { Auth } from "aws-amplify";
const protectedRoute = (Comp, route = "/login") => (props) => {
const navigate = useNavigate();
const [corps, setCorps] = useState(<></>);
const checkAuthState = async () => {
try {
await Auth.currentAuthenticatedUser();
console.log("React Router user authenticated ");
} catch (err) {
console.log("React Router we have an error");
return navigate(route);
}
};
useEffect(() => {
checkAuthState();
setCorps(<Comp {...props} />);
}, []);
return corps;
};
export default protectedRoute;