React组件onChange修改State异常:属性被添加至数组外部
解决React编辑表单中State属性修改错误的问题
问题根源
后端返回的员工数据是包含单个对象的数组(如[{ "ID":1, "FIRSTNAME": "JOE", "SECONDNAME":"SMITH"}]),但你直接将整个数组赋值给了data状态。当调用handleChange时,使用{...data}会展开数组元素,导致新属性被添加到数组外部,形成[{...}, "SECONDNAME":"MARK"]的错误结构。
修复步骤
1. 修正State数据赋值
在useEffect中,从后端返回的数组里取出第一个元素作为员工对象(根据ID查询只会返回一条记录),赋值给data:
useEffect( function (){ async function getEmployee(){ const URL = `http://127.0.0.1:8888/api/payroll/${id}` try{ const res = await fetch(URL, { method: 'GET', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }) const list = await res.json() // 取数组第一个元素,为空则用空对象兜底 setData(list[0] || {}) }catch(error){ console.log(error); } } getEmployee() }, [id] // 依赖项改为id,避免不必要的重渲染 );
2. 优化handleChange函数
现在data是单个对象,原有的handleChange可以正常修改属性。推荐使用函数式更新,避免状态更新的竞态问题:
function handleChange(event){ setData(prevData => ({...prevData, [event.target.name]: event.target.value})); }
3. 表单输入值添加兜底处理
为避免初始状态为空时的取值错误,给输入框的value添加可选链和空值兜底:
// FIRSTNAME输入框 value={data?.FIRSTNAME || ''} // LASTNAME输入框 value={data?.LASTNAME || ''}
4. 修复后端SQL错误
你的后端更新接口中,SQL语句重复设置了FIRSTNAME,需修改为对应字段,同时改用参数绑定避免SQL注入风险:
exports.updateEmployee = async(req, res, next) => { let id = req.params.id; // 使用参数绑定替代字符串拼接 const queryUpdate = ` UPDATE table_name SET FIRSTNAME = :firstname, LASTNAME = :lastname WHERE ID = :id ` let connection; oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT; oracledb.autoCommit = true; try{ connection = await oracledb.getConnection(); const update = await connection.execute(queryUpdate, { firstname: req.body.FIRSTNAME, lastname: req.body.LASTNAME, id: id }); res.status(200).json({update}) }catch(error){ console.log(error); next(error) } }
内容的提问来源于stack exchange,提问作者MarioJey
相关产品推荐
相关产品推荐

