我正在尝试使用reactjs通过调用axios创建用户配置文件。但我只能在使用Effect时看到更新的状态,而在其他地方看不到。在loginPage中。js,我正在尝试获取entryfirstName、entryLastName和role的最新状态,并将其发布到登录函数中,该函数将返回到我的userProvider.js中。我不知道如何更新状态,所以任何反馈都比我得到的要好。
我是新手反应,我无法解决这个问题,所以任何帮助将不胜感激!
这是我的登录页面代码.js
export default function SignIn() {
const { login } = useContext(UserContext);
const [email_input, setEmail] = useState('');
const [password_input, setPassword] = useState('');
const [entryfirstName, setFirstName] = useState('');
const [entrylastName, setlastName] = useState('');
const [role, setRole] = useState('');
const [entryuser, setEntryUser] = useState({});
const baseURL = 'http://samplesite.org/';
const handleEmailInputChange = event => {
setEmail(event.target.value);
};
const handlePasswordInputChange = event => {
setPassword(event.target.value);
};
const gatherData = async () => {
try {
const userlogins = await axios.get(`${baseURL}/user`);
setEntryUser(userlogins.data.users);
}
catch (error) {
console.log(error);
}
};
const updateData = (loggedin_id, userFirst, userLast) => {
setRole(loggedin_id);
setFirstName(userFirst);
setlastName(userLast);
}, [role, entryfirstName, entrylastName]);
const submit = () => {
if (email_input === null || password_input === null || email_input === "" || password_input === "") {
alert("Enter username and password");
}
else {
if (entryuser.map(x => x.email === email_input && x.password === password_input)) {
console.log("Email and Password exists");
const loggedin = entryuser.filter(obj => obj.email === email_input);
const loggedin_role = loggedin.map(({ role }) => `${role}`);
const loggedin_id = loggedin_role.toString();
const userNames_1 = loggedin.map(({ firstName }) => `${firstName}`);
const userNames_2 = loggedin.map(({ lastName }) => `${lastName}`);
const userFirst = userNames_1.toString();
const userLast = userNames_2.toString();
updateData(loggedin_id, userFirst, userLast);
}
else {
alert("User Does not Exist.");
}
}
}
useEffect(() => {
gatherData();
console.log('useEffect role: ', role);
console.log('useEffect firstname: ', entryfirstName);
console.log('useEffect lastname: ', entrylastName);
}, [role, entryfirstName, entrylastName]);
const handleClick = (event) => {
event.preventDefault();
submit();
console.log('role: ', role);
console.log('firstname: ', entryfirstName);
console.log('lastname: ', entrylastName);
login(entryfirstName, entrylastName, email_input, password_input, role);
}
这是userProvider.js代码
import React from "react";
import UserContext from "./UserContext";
const UserProvider = ({ children }) => {
const [user, setUser] = React.useState({
firstName: '',
lastName: '',
email: '',
role: '',
auth: false
});
const login = (firstName, lastName, email, password, role) => {
setUser((user) => ({
firstName: firstName,
lastName: lastName,
email: email,
password: password,
role: role,
auth: true,
}));
};
const logout = () => {
setUser((user) => ({
firstName: '',
lastName: '',
email: '',
password: '',
role: '',
auth: false,
}));
};
return (
<UserContext.Provider
value={{
user,
login,
logout }}
>
{children}
</UserContext.Provider>
);
};
export default UserProvider;
我会调用axios:
注意:为什么调用所有用户?我认为这是不对的,也许axios.get(
${base URL}/user/${email});
对于大多数特定用户,最佳实践安全性或例如:
const login = async (firstName, lastName, email, password, role) => {
if(firstName && lastName && email && password && role){
const { data } = await axios.post(session_url, {}, {
auth: {
email: email,
password: password
}
});
if(data){
setUser((user) => ({
firstName: data.user.firstName,
lastName: data.user.lastName,
email: data.user.email,
role: data.user.role,
auth: true,
}));
}
}
请阅读: 身份验证 - 公理
但我们还是继续吧
import {useState, useEffect} from "react";
import UserContext from "./UserContext";
const baseURL = 'http://samplesite.org/';
const UserProvider = ({ children }) => {
const [entryuser, setEntryUser] = useState({});
const [user, setUser] = useState({
firstName: '',
lastName: '',
email: '',
role: '',
auth: false
});
// you need a useEffect to verify if user is logged
useEffect(() => {
const getCurrentUser = localStorage.getItem("currentUser");
if (getCurrentUser) {
const currentUser = JSON.parse(getCurrentUser);
// now you need validate expireAt
// also make an axios call here, to check if you are authenticated on the backend
// validate all necessary
setUser((user) => ({
firstName: currentUser.firstName,
lastName: currentUser.lastName,
email: currentUser.email,
role: currentUser.role,
auth: true,
}));
}
},[])
const login = async (firstName, lastName, email, password, role) => {
try {
const userlogins = await axios.get(`${baseURL}/user`);
if(userLogins.data) {
setEntryUser(userlogins.data.users);
const loggedin = entryuser.filter(obj => obj.email === email);
const loggedin_role = loggedin.map(({ role }) => `${role}`);
const loggedin_id = loggedin_role.toString();
const userNames_1 = loggedin.map(({ firstName }) => `${firstName}`);
const userNames_2 = loggedin.map(({ lastName }) => `${lastName}`);
const userFirst = userNames_1.toString();
const userLast = userNames_2.toString();
// you need save this data in cookies or localstorage,
// I use crypto-js in localStorage
const currentUser = {
firstName: userFirst,
lastName: userLast,
role: loggedin_id,
expireAt: // here you need a time to expire sesion
}
localStorage.setItem("currentUser", JSON.stringify(currentUser));
setUser((user) => ({
firstName: userFirst,
lastName: userLast,
email: email,,
role: loggedin_id,
auth: true,
}));
};
}
catch (error) {
console.log(error);
}
};
const logout = () => {
setUser((user) => ({
firstName: '',
lastName: '',
email: '',
password: '',
role: '',
auth: false,
}));
};
return (
<UserContext.Provider
value={{
user,
login,
logout }}
>
{children}
</UserContext.Provider>
);
};
export default UserProvider;
注意:为什么您的登录会询问您的姓名和角色?最好从后端处理这些数据,您只能使用电子邮件和密码
interface IFormLogin {
email: string;
password: string;
firstName: string;
lastName: string;
role: string;
}
export default function SignIn() {
const { login } = useContext(UserContext);
const [formLogin, setFormLogin] = useState<IFormLogin>({
email: "";
password: "";
firstName: "";
lastName: "";
role: "";
})
const handleInputChange = event => {
setFormLogin((formState: IFormLogin) => ({
...formState,
[event.target.name]: event.target.value,
},
}));
};
const handleSubmit = (event) => {
event.preventDefault();
const {email, password, firstName, lastName, role} = formLogin;
if (!email && !password && !firstName && !lastName && !role) {
alert("Enter all data");
return;
}
login(firstName, lastName, email, password, role);
}
return(
<form onSubmit={handleSubmit}>
<input name="email" type="email" value={formLogin.email || ""} onChange={handleInputChange} />
<input name="password" value={formLogin.password || ""} onChange={handleInputChange} />
<input name="firstName" value={formLogin.firstName || ""} onChange={handleInputChange} />
<input name="lastName" value={formLogin.lastName || ""} onChange={handleInputChange} />
<input name="role" value={formLogin.role || ""} onChange={handleInputChange} />
<button type="submit">Login</button>
</form>
);
const { user } = useContext(UserContext);
console.log(user.firstName);
请不要在客户端的任何地方保存密码,我的意思是本地存储、会话存储、cookie、上下文、redux等。
您可以使用Json Web令牌来加密来自后端的数据,并将该令牌保存在本地存储中。
反应中的 JWT 身份验证
注意:我在任何情况下都使用TypeScript,如果您愿意,请省略该部分。
您可能知道,在正常模式下,当状态更新时,我们使用更新依赖项来获得通知,如下所示: 但在我的例子中,我的状态中有一个数组,我正在尝试在useEffect的循环中更新它,如下所示: 在本例中,每次forEach循环运行时,我都会得到初始val(我知道,因为val不是useffect的依赖项),但如果我将其作为依赖项,它将更新两次。解决这个问题的办法是什么? 编辑:基本上,我的意思是,当我在useffe
问题内容: 这是我使用的代码 我试图在客户表中的TotalP字段中设置一个值x。值x等于“产品”表中“客户ID”相同的对应价格的总和。 上面的代码返回错误 问题答案: 您可以使用DSum: 但是,这确实引发了一个问题,即当可以从查询中获取信息时,为什么要使用计算值来更新表。
对于类组件,在事件处理程序中调用批处理。但是,如果状态在事件处理程序之外更新并使用hook,会发生什么呢? 它会立即渲染?或者它将是,然后是?
我有多个云函数使用一个值,基本上是这样的: 问题是我想要更改页脚内容(由返回),但为了这样做(就我所研究的),我首先必须在代码中更改它,然后部署使用的每个云函数(和),这样页脚在每种类型的电子邮件上看起来都是一样的。 当然,我可以使用同时部署所有函数,但是我们曾经是多个开发人员,我们中的一些人将函数更新到我们不知道index.js中哪些函数与GCP中的相同(大约20个函数),我必须检查每一个函数,
问题内容: 我正在尝试仅更新数组状态中的一个元素,但不确定如何执行此操作。 State 设定状态 如果我想更改标记的第四个元素中的键,该怎么做? 谢谢 问题答案: 重要的一点是,我们不应该直接更改状态数组,而要始终在新数组中进行更改,然后使用setState更新状态值。 如 Doc 建议: 切勿直接更改this.state,将this.state视为不可变。 更新状态数组的基本流程是: 1- 首先
问题内容: constructor(){ super(); this.state = { address: { street:null, city:null, postalCode: null } }; } postalCodeChange(e){ this.setState.address.postalCode = e.target.value; console.log(this.state);