Reputation: 280
app.js
const [isLoggedIn, setIsLoggedIn] = useState(false);
useEffect(() => {
fetch('http://localhost:5000/usersystem/user/isloggedin', {
method: 'GET',
credentials: 'include',
mode: 'cors'
}).then(response => response.json())
.then(response => {
setIsLoggedIn(response.success);
})
}, []);
return (
<div className="App">
<AppContext.Provider value={{ isLoggedIn, setIsLoggedIn }}>
<Routes />
</AppContext.Provider>
</div>
);
}
routes.js
export default function Routes() {
return (
<Switch>
<ProtectedRoute exact path="/">
<Dashboard />
</ProtectedRoute>
<Route exact path="/login">
<Login />
</Route>
<Route>
<Notfound />
</Route>
</Switch>
);
}
protectedroute.jsx
import React from "react";
import { Route, Redirect, useLocation } from "react-router-dom";
import { useAppContext } from "../libs/ContextLib";
export default function ProtectedRoute({ children, ...rest }) {
const { pathname, search } = useLocation();
const { isLoggedIn } = useAppContext();
return (
<Route {...rest}>
{isLoggedIn ? (
children
) : (
<Redirect to={
`/login?redirect=${pathname}${search}`
} />
)}
</Route>
);
}
I have a node express app on port 5000, which handles user authentication with passport and cookie session. It works all good, the session cookies gets to the browser, and can read it and can send it back to authenticate the user.
However, in react, when i refresh the browser the user gets redirected to the login page instead of the dashboard, even with the session cookies in the browser.
It feels like the setIsLoggedIn(response.success)
in app.js, wont update isLoggedIn
before it gets to the ProtectedRoute
and redirects to login.
Im into this for 4 hours now, and couldnt solve it. Can someone please suggest me a way to do this, or tell me what is the problem, so when i refresh the page it wont redirect to login? Thanks.
Upvotes: 1
Views: 157
Reputation: 774
Your component is rendered once when you create the component.
Your setIsLoggedIn
will update the state and re-render it.
You could put in a Loader to wait for the data to come before displaying the page you want.
E.g:
function MyComponent () {
const [isLoggedIn, setIsLoggedIn] = useState(null);
useEffect(() => {
fetch('http://localhost:5000/usersystem/user/isloggedin', {
method: 'GET',
credentials: 'include',
mode: 'cors'
}).then(response => response.json())
.then((response, err) => {
if(err) setIsLoggedIn(false); // if login failure
setIsLoggedIn(response.success);
})
}, []);
if(isLoggedIn === null) return (<div>Loading</div>);
// this is only rendered once isLoggedIn is not null
return (
<div className="App">
<AppContext.Provider value={{ isLoggedIn, setIsLoggedIn }}>
<Routes />
</AppContext.Provider>
</div>
);
}
Upvotes: 1