ReactJs表单提交数据时出现额外空数组问题求助
问题描述
在ReactJs中通过表单提交数据时,除已插入的有效数据外,还额外获取到一个空数组。
提交按钮绑定的处理函数代码如下:
const [details, setDetails] = useState({ first_name: '', last_name: '' }); const onSubmit = (event) => { const person = { first_name: state.first_name, last_name: state.last_name } axios.post('localhost:3000/api/create.php', details) .then(response => { console.log(response.data); if (response.data) { setDetails([...details, person]) } }) .catch(error => { console.log(error); }) } const handleChange = (event) => { setDetails({ ...details, [event.target.name]: event.target.value }); }
所有输入字段的状态变更都通过统一的handleChange()函数处理。
错误原因
代码里有4个直接导致异常的问题:
- 变量引用错误:
onSubmit中构造person对象时,访问了未定义的state变量,当前表单数据实际存储在details状态中,这里会直接抛出引用错误,生成的person是无效值。 - 状态类型混乱:初始化时
details是存储单条表单数据的对象类型,但提交成功后执行setDetails([...details, person])时,将对象按数组展开后赋值,直接把details的类型从对象改成了数组。后续输入触发handleChange时,对数组做展开再挂载表单字段,会生成包含空索引、冗余空值的异常结构,提交时自然会带出多余的空数组。 - 未阻止表单默认行为:提交事件没有调用
event.preventDefault(),会触发浏览器原生表单同步提交跳转,和axios异步请求逻辑冲突,也会造成提交数据异常。 - 请求地址格式错误:接口地址缺省协议头,
localhost:3000会被axios识别为相对路径,请求发送到错误地址时可能返回非预期的空结构。
修复方案
核心原则是按职责拆分状态,不要混用不同类型的状态,修正后代码如下:
import { useState } from 'react'; import axios from 'axios'; // 单独存当前表单的输入值,始终保持对象类型 const [formData, setFormData] = useState({ first_name: '', last_name: '' }); // 单独存所有提交成功的人员列表,始终保持数组类型 const [personList, setPersonList] = useState([]); const onSubmit = (event) => { // 阻止表单默认提交刷新行为 event.preventDefault(); // 补全接口协议头,直接提交表单状态即可 axios.post('http://localhost:3000/api/create.php', formData) .then(response => { console.log(response.data); if (response.data) { // 新数据追加到专门的列表状态,不修改表单状态的类型 setPersonList([...personList, response.data]); // 提交成功后清空表单,方便下次输入 setFormData({ first_name: '', last_name: '' }); } }) .catch(error => { console.log(error); }) } const handleChange = (event) => { setFormData({ ...formData, [event.target.name]: event.target.value }); }
修复后注意两点:
- 不要中途修改同一个状态的类型,对象和数组的更新逻辑完全不同,混用必然导致数据结构异常。
- 访问状态时必须对应
useState定义的变量名,不要凭空使用未声明的变量。
内容的提问来源于stack exchange,提问作者alizoubair
相关产品推荐
相关产品推荐

