状态不是通过useState更新

时间:2020-08-02 00:44:36

标签: reactjs

我正在尝试将google登录功能添加到我的网站。我想在google api发送回响应但状态未更新时在googleOnSuccess函数中更新用户名状态。我正在使用“ react-google-login”软件包进行登录过程。导航栏组件中的updateToken()函数可以在用户登录时使用用户名再次呈现导航栏。

LoginModal.js

import React, { useState } from "react";
import axios from "axios";
import "../../App.scss";
import { Button, Modal, ModalHeader, ModalBody } from "reactstrap";
import GoogleLogin from "react-google-login";

const LoginModal = ({ updateToken }) => {
  const [modal, setModal] = useState(false);
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");

  const toggle = () => setModal(!modal);

  const handleSubmit = (e) => {
    e.preventDefault();

    axios
      .post("/login", {
        username: username,
        password: password,
      })
      .then((res) => res.data)
      .then((data) => {
        console.log(data);
        localStorage.setItem("userToken", data.access_token);
        localStorage.setItem("username", data.username);
        updateToken();
      })
      .catch((err) => {
        console.log(err);
      });
  };

  const googleOnSuccess = (res) => {
    console.log(res);
    const userEmail = res.profileObj.email;
    setUsername(userEmail.substring(0, userEmail.indexOf("@")));

    // console.log(`Username: ${username}`);
    localStorage.setItem("userToken", res.tokenObj.access_token);
    localStorage.setItem("username", username);
    updateToken();
    alert("Logged In Successfully");
  };

  const googleOnFailure = (res) => {
    console.log(res);
    alert("Log In Failed");
  };

  return (
    <div>
      <Button className="nav-button login-button" color="link" onClick={toggle}>
        LOG IN
      </Button>

      <Modal className="auth-modal" isOpen={modal} toggle={toggle}>
        <ModalHeader className="modal-header" toggle={toggle}>
          Log in
        </ModalHeader>
        <ModalBody className="modal-body">
          <GoogleLogin
            clientId="1087910724182-02v9tf6jm6h867i3vd81rui2dm4b6jvb.apps.googleusercontent.com"
            render={(renderProps) => (
              <Button
                onClick={renderProps.onClick}
                disabled={renderProps.disabled}
                color="link"
                className="google-button"
              >
                <i class="fab fa-google"></i>
                CONTINUE WITH GOOGLE
              </Button>
            )}
            onSuccess={googleOnSuccess}
            onFailure={googleOnFailure}
            cookiePolicy={"single_host_origin"}
          />
          <form method="POST" onSubmit={handleSubmit}>
            <div className="input-buttons-wrapper">
              <input
                type="text"
                name="username"
                placeholder="USERNAME"
                onChange={(e) => setUsername(e.target.value)}
                required
              />
              <input
                type="password"
                name="password"
                placeholder="PASSWORD"
                onChange={(e) => setPassword(e.target.value)}
                required
              />
            </div>
            <Button
              type="submit"
              className="modal-login-button"
              color="primary"
              onClick={toggle}
            >
              LOG IN
            </Button>
          </form>
          <p className="go-to-signup">New to FakeReddit? SIGN UP </p>
        </ModalBody>
      </Modal>
    </div>
  );
};

export default LoginModal;


1 个答案:

答案 0 :(得分:0)

由于设置状态是异步的,因此无法保证在您尝试在此处使用时将其设置

localStorage.setItem("username", username);

当您想在设置状态的同一函数中执行类似的操作时,最好使用与设置状态相同的值。在这种情况下,似乎是

userEmail.substring(0, userEmail.indexOf("@"))

使用该值作为您的localStorage.setItem行,而不是直接使用状态对象,因为它可能尚未更新。