I am trying to setup a context in React to handle user information which will be called once a user has logged in to the system. However, I am having trouble setting the user in the first place.
As it is, the user will enter their login info, and selected a role from a dropdown list. The API then returns a result based on the login info. I am trying to update the user context based on that result, but the user value in UserContext just ends up as undefined when I try to set it with useUserUpdate? what am I doing wrong here?
I have tried making the custom hook, useUserUpdate, to handle manipulating the user state, but it is not working and I am rather lost. I think this is where the issue is coming from as I have console.log all over the place and have seen that when calling this hook is when user becomes undefined. Any help that could be provided would be greatly appreciated.
App.js
import React from "react";
import { useUser } from "./contexts";
import { UserContextProvider } from "./contexts";
//import page components
import LoginForm from "./sharedComponents/LoginForm";
import WorkflowTemplate from "./workflows/WorkflowTemplate";
import "./App.css";
function App() {
const user = useUser();
return (
<UserContextProvider>
<div className="App">
{user != null ? <WorkflowTemplate /> : <LoginForm />}
</div>
</UserContextProvider>
);
}
export default App;
contexts.js
import React, { createContext, useState, useContext } from "react";
import Cookies from "universal-cookie";
const UserContext = createContext();
const UpdateUserContext = createContext();
const Cookie = new Cookies();
export const useUser = () => {
return useContext(UserContext);
};
export const useUserUpdate = () => {
return useContext(UpdateUserContext);
};
export const UserContextProvider = ({ children }) => {
const [user, setUser] = useState({
email: "test",
name: "",
id: "",
role: "",
});
console.log(user);
const updateUser = ({ user }) => {
setUser({ user });
console.log("user passed to context prov");
console.log(user);
};
return (
<UserContext.Provider value={user}>
<UpdateUserContext.Provider value={updateUser}>
{children}
</UpdateUserContext.Provider>
</UserContext.Provider>
);
};
LoginForm.js
import React, { useState, useEffect } from "react";
import {
i_sAccessToken,
i_sGetLoggedInUser,
i_sGETOrgs,
} from "../publicFunctions/identity_serviceAPI";
import { useUser, useUserUpdate } from "../contexts";
import Cookies from "universal-cookie";
import "../App.css";
function LoginForm() {
const Cookie = new Cookies();
const user = useUser();
const userUpdate = useUserUpdate();
const [details, setDetails] = useState({
email: "",
role: "",
password: "",
});
const submitHandler = (event) => {
event.preventDefault();
Login(details);
setDetails({ email: "", password: "", role: "" });
};
const Login = (details) => {
if (details.email === "") return alert("No email entered");
if (details.password === "") return alert("No password entered");
if (details.role === "") return alert("Please select a role");
//call API here to check username and save JWT
i_sAccessToken(details).then((result) => {
if (result.detail === "Incorrect email or password") {
alert("Incorrect email or password");
} else {
//if result does not return error set cookie
Cookie.set("JWT", result.access_token);
//get USER info from API
i_sGetLoggedInUser().then((result) => {
userUpdate({
...user,
email: result.email,
name: result.name,
id: result.id,
role: details.role,
});
});
}
});
};
return (
<form onSubmit={submitHandler}>
<div className="form-inner">
<h2>Login</h2>
{/*{error != "" ? <div className="error">{error} </div> : ""}*/}
<div className="form-group">
<label htmlFor="email">Email: </label>
<input
type="text"
name="name"
id="name"
onChange={(event) =>
setDetails({ ...details, email: event.target.value })
}
value={details.email}
/>
</div>
<div className="form-group">
<label htmlFor="password">Password: </label>
<input
type="password"
password="password"
id="password"
onChange={(event) =>
setDetails({ ...details, password: event.target.value })
}
value={details.password}
/>
</div>
<div>
<label htmlFor="role">Enter Role: </label>
<select
onChange={(event) =>
setDetails({ ...details, role: event.target.value })
}
value={details.role}
>
<option value="">Select Role</option>
<option value="Analyst">Analyst</option>
<option value="Manager">Manager</option>
<option value="Sample admin">Sample admin</option>
<option value="Developer">Developer</option>
</select>
</div>
<input type="submit" value="LOGIN" />
</div>
</form>
);
}
export default LoginForm;