React下拉选框数据存储失败,报500内部服务器错误求助
问题分析与修复方案
核心问题排查
你遇到的500内部服务器错误主要由两处代码错误导致:
1. Joi验证语法错误(后端model.js)
在validate函数中,enum的调用方式错误,应该是方法调用而非数组访问,这会直接导致服务器运行时崩溃。
2. React下拉选框配置错误(前端index.jsx)
- 下拉选框未绑定
onChange事件,无法将选中值同步到组件状态 - 选项值设置为
"1"和"2",与后端Schema要求的"active"/"inactive"不匹配 - 未绑定
value属性到状态值,也未添加required校验
修复代码
后端model.js修正
const mongoose = require('mongoose'); const jwt = require('jsonwebtoken'); const joi = require('joi'); const userSchema = new mongoose.Schema({ firstName:{type: String, required: true}, lastName:{type: String, required: true}, email:{type: String, required: true}, password:{type: String, required: true}, status:{type: String, enum: ['active', 'inactive'],required : true }, }); userSchema.methods.generateAuthToken = function(){ const token = jwt.sign({_id:this._id}, process.env.JWTPRIVATEKEY) return token } const User = mongoose.model("user", userSchema); const validate = (data) => { const schema = joi.object({ firstName:joi.string().required().label("First Name"), lastName:joi.string().required().label("Last Name"), email: joi.string().email().required().label("Email"), password: joi.string().required().label("password"), // 修正enum调用方式,同时设置有意义的label status:joi.string().enum(['active', 'inactive']).required().label("Status") }); return schema.validate(data) } module.exports = {User, validate}
前端index.jsx修正
import { useState } from "react"; import axios from "axios"; import { Link, useNavigate } from "react-router-dom"; import styles from "./styles.module.css"; const Signup = () => { const [data, setData] = useState({ firstName: "", lastName: "", email: "", password: "", status: "", }); const [error, setError] = useState(""); const navigate = useNavigate(); const handleChange = ({ currentTarget: input }) => { setData({ ...data, [input.name]: input.value }); }; const handleSubmit = async (e) => { e.preventDefault(); try { const url = "http://localhost:8080/api/user"; const { data: res } = await axios.post(url, data); navigate("/login"); console.log(res.message); } catch (error) { if ( error.response && error.response.status >= 400 && error.response.status <= 500 ) { setError(error.response.data.message); } } }; return ( <div className={styles.signup_container}> <div className={styles.signup_form_container}> <div className={styles.left}> <h1>Welcome Back</h1> <Link to="/login"> <button type="button" className={styles.white_btn}> Sign in </button> </Link> </div> <div className={styles.right}> <form className={styles.form_container} onSubmit={handleSubmit}> <h1>Create Account</h1> <input type="text" placeholder="First Name" name="firstName" onChange={handleChange} value={data.firstName} required className={styles.input} /> <input type="text" placeholder="Last Name" name="lastName" onChange={handleChange} value={data.lastName} required className={styles.input} /> <input type="email" placeholder="Email" name="email" onChange={handleChange} value={data.email} required className={styles.input} /> <input type="password" placeholder="Password" name="password" onChange={handleChange} value={data.password} required className={styles.input} /> {/* 修正下拉选框:绑定onChange、value,修正选项值,添加required */} <select name="status" onChange={handleChange} value={data.status} required className={styles.input} > <option value="">请选择状态</option> <option value="active">active</option> <option value="inactive">inactive</option> </select> {error && <div className={styles.error_msg}>{error}</div>} <button type="submit" className={styles.green_btn}> Sign Up </button> </form> </div> </div> </div> ); }; export default Signup;
额外建议
- 后端需在路由处理中捕获
validate函数返回的错误,返回400状态码和错误信息,避免直接抛出500错误:
// 示例路由处理逻辑 const {User, validate} = require('./model'); router.post('/api/user', async (req,res)=>{ const {error} = validate(req.body); if(error) return res.status(400).send(error.details[0].message); // 后续创建用户逻辑 });
- 可以考虑将下拉选项的枚举值抽离为常量,前后端共用,避免重复定义导致不一致。
内容的提问来源于stack exchange,提问作者Darius Elijah
相关产品推荐
相关产品推荐

