React Hooks+Axios向ASP.NET Core API提交嵌套数据失败问题
问题:React提交学生数据时subjectName未被传入API
我使用React Hooks结合Axios向ASP.NET Core API提交学生数据,点击提交后仅studentName和classId成功提交,subjectName未被传入。通过Swagger测试API时提交功能正常,问题出在React端。
API预期请求结构
{ "studentId": 0, "studentName": "string", "classId": 0, "class": { "classId": 0, "classNo": 0 }, "subject": [ { "subjectId": 0, "subjectName": "string" } ] }
React代码
import axios from 'axios'; import React, { useState, useEffect } from 'react'; import { Link, useNavigate } from 'react-router-dom'; export default function CreateStudent() { let navigate = useNavigate(); const [students, setStudent] = useState({ studentName: "", classId:"", subject:[ { subjectName: "", } ] }); const [classes, setClass] = useState([]); useEffect(() => { loadClassess(); }, []); const loadClassess = async () => { const result = await axios.get('https://localhost:7076/api/Classes'); setClass(result.data); }; const onInputChange = (e) => { setStudent({ ...students, [e.target.name]: e.target.value }); }; const onSubmit = async (e) => { e.preventDefault(); await axios.post('https://localhost:7076/api/Students', students); navigate("/"); }; return ( <div className="container"> <div className="row"> <div className="col-md-6 offset-md-3 border rounded p-4 mt-2 shadow"> <h2 className="text-center m-4">Insert New Student</h2> <form onSubmit={(e) => onSubmit(e)}> <div className="mb-3"> <label htmlFor="studentName" className="form-label"> Student Name </label> <input type={"text"} className="form-control" placeholder="Enter Name" name="studentName" value={students.studentName} onChange={(e) => onInputChange(e)} /> </div> <div className="mb-3"> <label htmlFor="classId" className="form-label"> Select Classes </label> <select name="classId" value={students.classId} className="form-control" onChange={(e) => onInputChange(e)} > <option value="">Select Class</option> { classes.map(classe => { return( <option key={classe.classId} value={classe.classId}>{classe.classNo}</option> ) }) } </select> </div> <div className="mb-3"> <label htmlFor="subjectName" className="form-label"> Subject Name </label> <input type={"text"} className="form-control" placeholder="Enter Subject Name" name="subjectName" value={students.subject.subjectName} onChange={(e) => onInputChange(e)} /> </div> <button type="submit" className="btn btn-outline-primary"> Submit </button> <Link className="btn btn-outline-danger mx-2" to="/"> Cancel </Link> </form> </div> </div> </div> ) }
问题表现
提交后仅学生姓名和班级ID被存入数据库,科目名称字段缺失。
问题原因及修复方案
核心问题
- 输入框绑定错误:
students.subject是数组类型,不能直接通过students.subject.subjectName取值,正确路径应为students.subject[0].subjectName。 - 状态更新函数不支持嵌套结构:当前
onInputChange只能更新一级属性,无法处理subject数组内的嵌套对象,输入时会给students新增一个subjectName属性,而非更新目标路径的值。
修复步骤
方案一:支持嵌套属性的通用更新函数
- 修改科目输入框的
name属性为路径格式,同时修正value绑定:
<input type={"text"} className="form-control" placeholder="Enter Subject Name" name="subject.0.subjectName" // 用点路径标识嵌套位置 value={students.subject[0].subjectName} onChange={(e) => onInputChange(e)} />
- 重写
onInputChange函数,解析路径并更新嵌套对象:
const onInputChange = (e) => { const { name, value } = e.target; const pathArr = name.split('.'); const updatedStudent = { ...students }; let currentNode = updatedStudent; // 遍历到路径的倒数第二个节点 for (let i = 0; i < pathArr.length - 1; i++) { currentNode = currentNode[pathArr[i]]; } // 更新最终节点的值 currentNode[pathArr[pathArr.length - 1]] = value; setStudent(updatedStudent); };
方案二:针对单条subject的简化处理
如果仅需处理单个科目,可单独写一个更新函数:
- 修改科目输入框的
onChange绑定:
<input type={"text"} className="form-control" placeholder="Enter Subject Name" value={students.subject[0].subjectName} onChange={(e) => handleSubjectChange(e)} />
- 添加专用的科目更新函数:
const handleSubjectChange = (e) => { const updatedSubjects = [...students.subject]; updatedSubjects[0].subjectName = e.target.value; setStudent({ ...students, subject: updatedSubjects }); };
内容的提问来源于stack exchange,提问作者Ibrahim Al-Habian
相关产品推荐
相关产品推荐

