React Router Authenticated Route Is Redirecting When I Refresh the Page

I am getting redirected to main page after page refresh even if the user is authenticated in private route react?

Issue

The issue is that both your initial currentUser and loading state are falsey.

const [currentUser, setCurrentUser] = useState<null | any>(null);
const [loading, setLoading] = useState<boolean>(false);

This means when the app is initially loading/mounting, if the user is attempting to access a protected route they are redirected before the firsbase auth check has had a chance to complete.

export const PrivateRoute: React.FC<Props> = ({ component: Component, ...rest }) => {
const _authContext = useContext(authContext);
const { currentUser, loading } = _authContext;
console.log(currentUser);

return (
<Route
{...rest}
render={(props) => (!currentUser && !loading
? <Redirect to='/' />
: <Component />
)}
/>
);
};

Solution

One possible solution is to start with an initially loading state of true or an indeterminant currentUser value that doesn't equal your verified unauthenticated state, and to use an explicit check for either before committing to redirecting or rendering the protected component.

Example:

const [currentUser, setCurrentUser] = useState<null | any>();
const [loading, setLoading] = useState<boolean>(true);

...

export const PrivateRoute: React.FC<Props> = (props) => {
const _authContext = useContext(authContext);
const { currentUser, loading } = _authContext;
console.log(currentUser);

if (currentUser === undefined || loading) {
return null; // or loading spinner, etc...
}

return currentUser
? <Route {...props} />
: <Redirect to='/' />;
};

React Router Dom Protected Route Always Redirects to Login during refresh page

You can use localStorage in order to handle the Authentication.
In login function you can set the value of auth state like this localStorage.setItem('isAuth', authenticated). In logout function localStorage.removeItem('isAuth'). Change the PrivateRoute as per the localStorage

import React from 'react';
import { Route, Redirect } from 'react-router-dom';

const PrivateRoute = ({
component: Component,
...rest
}) => {
const isAuth = localStorage.getItem('isLoggedIn');
return (
<Route
{...rest}
render={props =>
isAuth ? (
<Component {...props} {...rest} />
) : (
<Redirect
to={{
pathname: "/admin/login",
state: {
from: props.location
}
}}
/>
)
}
/>
);
}

export default PrivateRoute;

React Router - When unauthenticated refreshing on plain route pages redirects me to index page

It's something to do with the order of execution. The redux state gets erased when you refresh so you need the store.dispatch(setCurrentUser(decoded)) to get called before the PrivateRoute tries to render. It's not obvious to me precisely where it's going wrong because the if (localStorage.jwtToken) { block is not async, though the dispatch might be?

I would recommend setting the initialState in authReducer to isAuthenticated: null and update to either true or false once you've examined the token. Right now your PrivateRoute only knows two states: authenticated and unauthenticated. We need it to understand a third which is "I don't know yet". In your PrivateRoute you would render nothing or a loading spinner while isAutheticated is null. Don't render the Redirect until you have a definite false.

Always getting redirected to homepage on refresh from any route in app

The problem is that setLoggedIn(true); is executed after the redirect action:

You need to check if user has been loaded or not. You can initialize loggedIn to null

const [loggedIn, setLoggedIn] = useState(null);

useEffect(() => {
const loggedUser = localStorage.getItem('user');
setLoggedIn(Boolean(loggedUser));
}, []);

Then you can ignore render the routes if loggedIn === null

return (
<div>
{ loggedIn !== null &&
<Router>
...
</Router>
}

</div>
);


Related Topics



Leave a reply



Submit