Reputation: 47
I have following problem - my Context works good, until I refresh my page. For example if I'm on ProtectedRoute and try to refresh, my "loggedIn" property sets for a moment to false and redirects me to home page.
Context:
export const Context = createContext();
export const ContextProvider = (props) => {
const [loggedIn, setLoggedIn] = useState(false);
const [userRole, setUserRole] = useState('');
useEffect(() => {
if (localStorage.getItem("loggedIn") === "true") {
setLoggedIn(true);
}
else {
setLoggedIn(false);
}
}, [])
return (
<Context.Provider
value={[loggedIn, userRole, setLoggedIn]}>
{props.children}
</Context.Provider>
);
}
ProtectedRoute:
const ProtectedRoute = ({ component: Component, ...rest }) => {
const [loggedIn] = useContext(Context);
return (
<Route
{...rest}
render={(props) =>
loggedIn ? <Component {...props} /> : <Redirect to='/login' />
}
/>
);
};
export default ProtectedRoute;
index.js:
ReactDOM.render(
<ContextProvider>
<App />
</ContextProvider>,
document.getElementById('root')
);
reportWebVitals();
App.js:
export default function App() {
const [loggedIn] = useContext(Context);
console.log(loggedIn)
return (
<div className="background">
<Router>
<Navigation />
<Scores />
<div className="content">
<Route exact path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/register" component={Register} />
<ProtectedRoute path="/players/:id" exact={true} component={PlayerStats} />
<ProtectedRoute path="/players" component={PlayerList} />
<ProtectedRoute path="/team/:id" exact={true} component={MyTeamDetails} />
<ProtectedRoute path="/myteams" exact={true} component={MyTeamList} />
<ProtectedRoute path='/logout' />
</div>
</Router>
</div>
);
}
And that's my function to handle login:
export const Login = () => {
const [loggedIn, userRole, setLoggedIn] = useContext(Context);
const [password, setPassword] = useState("")
const [showPassword, setShowPassword] = useState(false);
const [username, setUsername] = useState("");
const updateUsername = (e) => {
setUsername(e.target.value)
}
const updatePassword = (e) => {
setPassword(e.target.value)
}
function handleSubmit(e) {
e.preventDefault();
axios({
method: 'post',
url: 'https://localhost:44324/authentication/login',
data: {
"login": username,
"password": password
},
}).then((res) => {
if (res.data.result == "SUCCESS") {
localStorage.setItem('loggedIn', 'true');
setLoggedIn(true);
} else {
console.log(res.data);
}
}).catch((error) => {
console.log(error);
});
}
To specify - if I refresh page when I'm on "/myteams", it redirect me to "/". I tried to check my loggedIn state and it seems like it's dissappears for really short time upon refresh, then comes back to normal.
Upvotes: 2
Views: 303
Reputation: 64657
setState
(and it's hooks variant) runs asynchronously, so when you do:
const [loggedIn, setLoggedIn] = useState(false);
useEffect(() => {
if (localStorage.getItem("loggedIn") === "true") {
setLoggedIn(true);
}
else {
setLoggedIn(false);
}
}, [])
There will be a moment where loggedIn
is false
.
You could just do:
const [loggedIn, setLoggedIn] = useState(localStorage.getItem("loggedIn") === "true");
and it should avoid the issue.
Upvotes: 1