You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

登录验证通过后如何实现页面跳转?

解决方案

核心逻辑:Formik 的 onSubmit 会自动先执行字段校验,只有校验通过后才会调用 handleLogin,所以只需在 handleLogin 中根据后端返回的登录结果,决定是否执行页面跳转即可,完全不会跳过校验流程。

前端代码修改

import "../App.css";
import * as yup from "yup";
import { ErrorMessage, Formik, Form, Field } from "formik";
import Axios from "axios";
import { useNavigate } from "react-router-dom";

const Login = () => {
  const navigate = useNavigate(); // 启用useNavigate

  const handleLogin = (values) => {
    Axios.post("http://localhost:3001/login", {
      email: values.email,
      password: values.password,
    }).then((response) => {
      const resData = response.data;
      alert(resData.msg);
      // 仅当后端返回登录成功时执行跳转
      if (resData.msg === "用户登录成功") {
        navigate("/Home");
      }
    }).catch(() => {
      alert("登录请求失败,请稍后重试");
    });
  };

  const validationsLogin = yup.object().shape({
    email: yup
      .string()
      .email("邮箱格式无效")
      .required("邮箱为必填项"),
    password: yup
      .string()
      .min(8, "密码至少需要8个字符")
      .required("密码为必填项"),
  });

  return (
    <div className="container">
      <h1>登录</h1>
      <Formik
        initialValues={{}}
        onSubmit={handleLogin}
        validationSchema={validationsLogin}
      >
        <Form className="login-form">
          <div className="login-form-group">
            <Field name="email" className="form-field" placeholder="邮箱" />

            <ErrorMessage
              component="span"
              name="email"
              className="form-error"
            />
          </div>
          {/* 密码字段 */}
          <div className="form-group">
            <Field name="password" className="form-field" placeholder="密码" />

            <ErrorMessage
              component="span"
              name="password"
              className="form-error"
            />
          </div>

          <button className="button" type="submit">
            登录
          </button>
        </Form>
      </Formik>
    </div>
  );
};

export default Login;

后端代码优化(建议同步调整)

将返回提示改为中文,同时完善错误处理逻辑:

const db = mysql.createPool({
  host: "localhost",
  user: "root",
  password: "",
  database: "bd_login_cadastro",
});

app.use(express.json());
app.use(cors());

app.post("/register", (req, res) => {
  const email = req.body.email;
  const password = req.body.password;

  db.query("SELECT * FROM usuarios WHERE email = ?", [email], (err, result) => {
    if (err) {
      return res.status(500).send({ msg: "服务器查询错误" });
    }
    if (result.length === 0) {
      bcrypt.hash(password, saltRounds, (err, hash) => {
        if (err) {
          return res.status(500).send({ msg: "密码加密失败" });
        }
        db.query(
          "INSERT INTO usuarios (email, password) VALUES (?,?)",
          [email, hash],
          (error) => {
            if (error) {
              return res.status(500).send({ msg: "用户注册失败" });
            }
            res.send({ msg: "用户注册成功" });
          }
        );
      });
    } else {
      res.send({ msg: "该邮箱已被注册" });
    }
  });
});

app.post("/login", (req, res) => {
  const email = req.body.email;
  const password = req.body.password;

  db.query("SELECT * FROM usuarios WHERE email = ?", [email], (err, result) => {
    if (err) {
      return res.status(500).send({ msg: "服务器查询错误" });
    }
    if (result.length > 0) {
      bcrypt.compare(password, result[0].password, (error, response) => {
        if (error) {
          return res.status(500).send({ msg: "密码验证失败" });
        }
        if (response) {
          res.send({ msg: "用户登录成功" });
        } else {
          res.send({ msg: "密码错误" });
        }
      });
    } else {
      res.send({ msg: "该用户未注册" });
    }
  });
});

关键说明

  • 校验逻辑:Formik 会严格按照 validationSchema 完成字段校验,校验不通过时不会触发 handleLogin,彻底避免跳过校验的问题。
  • 跳转触发:只有后端明确返回登录成功的标识时,才调用 navigate 跳转,确保只有账号密码在数据库验证通过后才进入主页。
  • 异常处理:添加请求异常捕获,避免网络问题导致无提示的静默错误。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 04:45:41