登录验证通过后如何实现页面跳转?
解决方案
核心逻辑: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
相关产品推荐
相关产品推荐

