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

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;

额外建议

  1. 后端需在路由处理中捕获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);
    
    // 后续创建用户逻辑
});
  1. 可以考虑将下拉选项的枚举值抽离为常量,前后端共用,避免重复定义导致不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 21:06:15