have a login in form, once the login completed i try to set the context to a specific value
import { UserStatus, useUserStatus } from "../context/context";
const completeLoginAction = async (credentials: any) => {
var loginSuccess = await authService.login(credentials);
if (loginSuccess) {
setUserStatus(1);
localStorage.setItem("userStatus", JSON.stringify(userStatus));
console.log("USERSTATIS AFTER LOGIN IS" userStatus);
console.log(
"local storage on login is " localStorage.getItem("userStatus")
);
return true;
} else {
return false;
}
};
however this is always the default value of 0
even when hardcoding it to 1, its not changing at all
my context.tsx
import { createContext, useContext } from "react";
export enum UserStatus {
LoggedOff = 0,
LoggedIn = 1,
UserStatus,
}
export type UserStatusContextType = {
userStatus: UserStatus;
setUserStatus: (userStatus: UserStatus) => void;
};
export const UserStatusContext = createContext<UserStatusContextType>({
userStatus: UserStatus.LoggedOff,
setUserStatus: (userStatus) => console.warn("log on status unknown"),
});
export const useUserStatus = () => useContext(UserStatusContext);
cant workout why it retains the default value and doesnt set the new value
any ideas?
edit: my completed login form
mport React, { useContext, useEffect, useState } from "react";
import Button from "react-bootstrap/Button";
import Form from "react-bootstrap/Form";
import "bootstrap/dist/css/bootstrap.min.css";
import "./LoginPage.css";
import authService from "../../services/authService";
import { Navigate, useNavigate } from "react-router-dom";
import { UserStatus, useUserStatus } from "../context/context";
const LoginPage = () => {
const [username, setUserName] = useState("");
const [password, setPassword] = useState("");
const [errMsg, setErrMsg] = useState("");
const [sucess, setSuccess] = useState("");
const { userStatus, setUserStatus } = useUserStatus();
const navigate = useNavigate();
const handleUsernameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setUserName(e.target.value);
};
const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setPassword(e.target.value);
};
const handleSave = async (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
const credentials = {
Username: username,
Password: password,
};
var completed = await completeLoginAction(credentials);
// if (completed) {
// console.log("logged in");
// navigate("/");
// } else {
// showErrorMessage();
// }
};
const completeLoginAction = async (credentials: any) => {
var loginSuccess = await authService.login(credentials);
if (loginSuccess) {
setUserStatus(1);
localStorage.setItem("userStatus", JSON.stringify(userStatus));
console.log("USERSTATIS AFTER LOGIN IS" userStatus);
console.log(
"local storage on login is " localStorage.getItem("userStatus")
);
return true;
} else {
return false;
}
};
const showErrorMessage = () => {
let elms = document.getElementsByClassName(
"loginfailmessage"
) as HTMLCollectionOf<HTMLElement>;
for (var i = 0; i < elms.length; i ) {
elms[i].style.display = "block";
}
};
return (
<div className="container">
<div className="LoginForm">
<h1 className="Title">Login</h1>
<Form>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Username</Form.Label>
<Form.Control
type="text"
placeholder="Enter username"
onChange={handleUsernameChange}
name="username"
required
/>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
placeholder="Password"
onChange={handlePasswordChange}
name="password"
required
/>
</Form.Group>
<Button variant="primary" type="submit" onClick={handleSave}>
Submit
</Button>
</Form>
<h4 className="loginfailmessage" style={{ display: "none" }}>
Failed to login
</h4>
</div>
</div>
);
};
export default LoginPage;
CodePudding user response:
MyContext.ts
import { createContext, useContext } from 'react';
export type Status = 'pending' | 'ready';
export type ContextValue = {
signedIn: boolean,
status: Status
};
export interface Returns {
value: ContextValue
updateValue: (newValue: ContextValue) => void
}
/** defines the default value if none provided */
export const initialValue: ContextValue = {
signedIn: false,
status: 'pending'
};
export const MyContext = createContext<ContextValue>({
value: initialValue,
updateValue: (newValue) => {
return console.warn('DefaultContextCallback', newValue);
}
});
export const useMyContext = () => useContext(MyContext);
App.ts - or however high up it needs to be provided
import React, { useState } from 'react';
import { Component } from 'Component';
import { MyContext, initialValue ) from 'MyContext';
const App = () => {
const { value , updateValue } = useState(initialValue);
return (
<MyContext.Provider value={{ value, updateValue }} >
<App>
<Component/>
</App>
</MyContext.Provider>
)
}
Component.tsx
const Component = () => {
const { value, updateValue } = useMyContext();
}