I am using react context to handle the state and also to avoid prop drilling. When the user clicks on the Login button, it triggers the functions passed from UserContext to update the new state e.g setLoggedIn(true), setToken(response.token) and setUserNotfound(false) but it is not updating the new state? Why the code is not updating the new state?
What I have tried:
UserContext
import React, { useState, useContext } from "react";
export const UserContext = React.createContext();
export const UserLoginContext = React.createContext();
export function useUserContext(){
return useContext(UserContext)
}
export function useLoginContext(){
return useContext(UserLoginContext)
}
export function UserProvider({ children }) {
const [isLoggedIn, setLoggedIn] = useState(false);
const [userNotFound, setUserNotFound] = useState(false);
const [registerUser, setRegister] = useState(false);
const [token, setToken] = useState("");
function userLogin(data) {
setLoggedIn(data);
}
function userToken(res){
setToken(res.token);
}
function userFound(data){
setUserNotFound(data);
}
function registerNewUser(data){
setRegister(data);
}
return (
<UserContext.Provider
value={{
isLoggedIn,
userNotFound,
token,
registerUser
}}
>
<UserLoginContext.Provider value={{userLogin, userToken, userFound, registerNewUser}}>
{children}
</UserLoginContext.Provider>
</UserContext.Provider>
);
};
Login.jsx
<code>import React, { useState } from "react";
import { useHistory } from "react-router";
import { Container, Row, Col, Form, Button } from "react-bootstrap";
import { validateUser } from "../../api/User/Auth";
import { useTranslation } from "react-i18next";
import { useUserContext, useLoginContext } from "../../Context/UserContext";
const Login = ({ children }) => {
let history = useHistory();
const {
isLoggedIn,
userNotFound,
token
} = useUserContext();
const {userLogin, userToken, userFound} = useLoginContext();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const { t } = useTranslation();
function handleSubmit (e) {
e.preventDefault();
validateUser(email, password).then((res) => {
console.log(res);
if (res) {
if(res.status){
userLogin(true);
userToken(res.token);
userFound(false);
console.log(isLoggedIn, userNotFound);
console.log(`TOKEN: ${token}`);
history.push("/admin");
}
}
});
};
return (
<>
<Container className="login d-flex justify-content-center">
<Row>
<Col>
<Form className="form">
<Form.Group controlId="formBasicEmail">
<Form.Label>{t("login.email")}</Form.Label>
<Form.Control
type="email"
placeholder={t("login.e.text")}
size="lg"
value={email}
onChange={(e) => {
setEmail(e.target.value);
}}
/>
{userNotFound ? (
<Form.Text className="text-danger">
Email Address Not Found
</Form.Text>
) : (
""
)}
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>{t("login.password")}</Form.Label>
<Form.Control
type="password"
placeholder={t("login.password")}
size="lg"
value={password}
onChange={(e) => {
setPassword(e.target.value);
}}
/>
{userNotFound ? (
<Form.Text className="text-danger">
Invalid Password
</Form.Text>
) : (
" "
)}
</Form.Group>
<Button variant="primary" type="submit" onClick={handleSubmit}>
{t("nav.login")}
</Button>
</Form>
</Col>
</Row>
</Container>
</>
);
};
export default Login;</code>