Login.js
const submit = () => {
Axios.post("http://localhost:3001/login", data).then((res) => {
localStorage.setItem("bankDetails", res.data[0].acc_no);
navigate("/Home");
});
};
return (
<form onSubmit={submit}>
<input ... />
...
</form>
)
Home.js
import { useContext } from "react";
import { LoginContext, DetailsContext } from "../App";
function Account() {
const isValid = useContext(LoginContext);
const userDetails = useContext(DetailsContext);
const load = () => {
localStorage.removeItem("bankDetails");
window.location.reload();
}
return isValid ? (
<div className="personal-info">
<h3>Welcome {userDetails.Username}</h3>
<h3 onClick={load}>LogOut</h3>
</div>
) : (
<h1>You Need to Login First !!!</h1>
);
}
App.js
export const LoginContext = React.createContext();
export const DetailsContext = React.createContext();
function App() {
const username = localStorage.getItem("bankDetails");
const [userDetails, setUserDetails] = useState();
const [isValid, setisValid] = useState(false);
useEffect(() => {
if (username !== null) {
Axios.post("http://localhost:3001/userDetails", {
username: username,
}).then((res) => {
if (res.data.err) {
console.log("err");
} else {
setUserDetails(res.data.details[0]);
setisValid(true);
}
});
}
}, [username]);
return (
<LoginContext.Provider value={isValid}>
<DetailsContext.Provider value={userDetails}>
<Router>
<Routes>
<Route path="/Login" element={<Login />} />
<Route path="/Home" element={<Home />} />
</Routes>
</Router>
</DetailsContext.Provider>
</LoginContext.Provider>
);
}
Here, when I log out from the Home
page, the state gets updated and the page shows a login option, but after logging in again, the page again shows a login option untill refreshed, after refreshing the page, it displays the username?
Why does the context value does not reflect immediately ?
CodePudding user response:
That's because inside submit
function you didn't ask the context to update anything. Your App
component is not watching changes inside the localStorage
, the only thing you are updating after login. App
as you did checks the localStorage
only on load. That's why it works when you log in and then refresh the page.
What you can do that wouldn't change that much your current structure is first to export setisValid
as part of LoginContext.Provider
, like this:
<LoginContext.Provider value={{isValid,setisValid}}>
Then grab both of isValid
and setisValid
inside Login
component. Change your submit
function and add an useEffect
that would do the redirection. Like so:
const {isValid, setisValid} = useContext(LoginContext);
const submit = () => {
Axios.post("http://localhost:3001/login", data).then((res) => {
localStorage.setItem("bankDetails", res.data[0].acc_no);
setisValid(true);
};
useEffect(()=>{
if(isValid){
navigate("/home")
}
},[isValid])
And put isValid
inside the dependencies array of that useEffext
inside App
, and move username
inside the callback.
useEffect(() => {
const username = localStorage.getItem("bankDetails");
if (username !== null) {
Axios.post("http://localhost:3001/userDetails", {
username: username,
}).then((res) => {
if (res.data.err) {
console.log("err");
} else {
setUserDetails(res.data.details[0]);
setisValid(true);
}
});
}
}, [isValid]);