React 17.0.1 动态增删行表单scheduleNumber与costJson值绑定咨询
可落地的整合修复方案
先修正现有代码的硬伤(不改的话整合逻辑也跑不通)
- 通用输入函数里引用了未定义的
schuduleNumber变量,且数组拷贝逻辑错误:原写法const list = [...row, ...schuduleNumber]会把不存在的变量内容拼接到行数组中,替换为纯拷贝当前行数组即可 - 下拉框的
name属性写的是scheduleNo,和状态里定义的scheduleNumber字段名不匹配,就算走通用更新逻辑也无法正确存入值 - 两个独立的变更处理函数
setSelectedScheduleNumber、handleCostInput都没有接收当前操作的行索引,根本无法判断值要更新到哪一行的状态中
步骤1:重构通用输入变更函数
替换掉有问题的handleInputChange,采用不可变更新规范,确保普通文本字段、下拉框字段都能通过同一套逻辑更新:
const handleInputChange = (e, rowIndex) => { const { name, value } = e.target; const updatedRows = [...row]; // 展开生成新的行对象,避免直接修改原状态的对象引用,合并新的字段值 updatedRows[rowIndex] = { ...updatedRows[rowIndex], [name]: value }; setRow(updatedRows); };
注意:原代码里console.log(row)拿不到最新状态是因为React setState是异步执行的,属于正常现象,不要误以为值没有存进去,要验证的话可以在useEffect里监听row变化打印最新值
步骤2:整合scheduleNumber下拉框的逻辑
完全可以不需要单独的setSelectedScheduleNumber函数,直接让下拉框走通用的输入变更逻辑:
- 把下拉框的
name属性改成和状态字段完全一致的scheduleNumber - onChange绑定通用变更函数,传入当前循环的行索引
- 如果下拉选中后有联动需求(比如根据选中值自动填充其他字段、拉取接口数据),在onChange回调里先执行联动逻辑,再调用通用变更函数即可
修正后的下拉框代码:
<Form.Control as="select" value={x.scheduleNumber} name="scheduleNumber" onChange={(e) => { // 这里放原setSelectedScheduleNumber里的联动逻辑,比如根据选中值设置其他字段默认值 handleInputChange(e, i) }} >
步骤3:整合costJson嵌套字段的逻辑
costJson是行状态里的嵌套对象,不需要走原来的独立处理逻辑,只需要调整原handleCostInput的入参,支持传入当前行索引,把值写入对应行的costJson对象下即可:
- 改造
handleCostInput,实现嵌套对象的不可变更新
const handleCostInput = (e, rowIndex) => { const { name, value } = e.target; const updatedRows = [...row]; updatedRows[rowIndex] = { ...updatedRows[rowIndex], // 展开原有costJson对象,合并当前输入的数值 costJson: { ...updatedRows[rowIndex].costJson, [name]: Number(value) // 数值输入框转成数字类型存储,匹配数字输入的场景 } }; setRow(updatedRows); };
- 渲染cost输入框时,把当前行的索引传入事件回调
{costs?.map((cost) => { return ( <Form.Control type="number" name={cost.key} min="1" max={cost.value} onChange={(e) => handleCostInput(e, i)} /> ) })}
其他注意点
- 渲染代码里重复写了两个
name="payableTo"的输入框,注意核对字段名,避免值写错位置 - 新增、删除行的逻辑本身没有问题,只要每次状态更新都遵循不可变原则,就不会出现行值串位的问题
内容的提问来源于stack exchange,提问作者Deepak Murthy
相关产品推荐
相关产品推荐

