当前位置: 首页 > 知识库问答 >
问题:

如何在使用 onClick 函数时更新状态

湛铭
2023-03-14

我正在尝试使用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;

共有1个答案

麹飞航
2023-03-14

我会调用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

  • 在render函数中状态更新了,为何在函数内部中取这个状态时,这个状态不是最新的? 下面使用了selectedKeys状态,我在render和函数内部都打印了,打印的结果可看最后一张图。问题出现在第二次调用,函数里面的selectedKeys不是上一次更新数据 Card.tsx useTouch.ts 打印内容 无

  • 问题内容: 这是我使用的代码 我试图在客户表中的TotalP字段中设置一个值x。值x等于“产品”表中“客户ID”相同的对应价格的总和。 上面的代码返回错误 问题答案: 您可以使用DSum: 但是,这确实引发了一个问题,即当可以从查询中获取信息时,为什么要使用计算值来更新表。

  • 对于类组件,在事件处理程序中调用批处理。但是,如果状态在事件处理程序之外更新并使用hook,会发生什么呢? 它会立即渲染?或者它将是,然后是?

  • 我有多个云函数使用一个值,基本上是这样的: 问题是我想要更改页脚内容(由返回),但为了这样做(就我所研究的),我首先必须在代码中更改它,然后部署使用的每个云函数(和),这样页脚在每种类型的电子邮件上看起来都是一样的。 当然,我可以使用同时部署所有函数,但是我们曾经是多个开发人员,我们中的一些人将函数更新到我们不知道index.js中哪些函数与GCP中的相同(大约20个函数),我必须检查每一个函数,

  • 问题内容: 我正在尝试仅更新数组状态中的一个元素,但不确定如何执行此操作。 State 设定状态 如果我想更改标记的第四个元素中的键,该怎么做? 谢谢 问题答案: 重要的一点是,我们不应该直接更改状态数组,而要始终在新数组中进行更改,然后使用setState更新状态值。 如 Doc 建议: 切勿直接更改this.state,将this.state视为不可变。 更新状态数组的基本流程是: 1- 首先