React useReducer 更新表单对象:嵌套address字段更新问题求助
解决React受控表单中嵌套address对象的更新问题
方案一:使用带路径的name属性(通用型)
这种方法支持任意层级的嵌套对象,扩展性更强。
- 修改输入框的
name属性为嵌套路径格式:
<input className={style.bodylessInput} placeholder=" " type="text" maxLength={30} name="address.addressLine1" value={formData.address.addressLine1} onChange={handleChange} /> <!-- city/state/zip的输入框name分别设为"address.city"、"address.state"、"address.zip" -->
- 更新
formReducer以解析嵌套路径并更新对应字段:
const formReducer = (state, event) => { const { name, value } = event; const pathSegments = name.split('.'); // 深拷贝原状态,避免直接修改原对象 const updatedState = { ...state }; let currentNode = updatedState; // 遍历路径到倒数第二个节点,确保每一层都是新对象 for (let i = 0; i < pathSegments.length - 1; i++) { const segment = pathSegments[i]; currentNode[segment] = { ...currentNode[segment] }; currentNode = currentNode[segment]; } // 设置最后一个节点的值 currentNode[pathSegments[pathSegments.length - 1]] = value; return updatedState; };
handleChange函数保持不变:
function handleChange(event) { setFormData({ name: event.target.name, value: event.target.value, }); }
方案二:针对性判断address字段(简易型)
如果你的嵌套结构固定,不需要支持多层嵌套,可以用这种更直接的方式。
- 输入框的
name保持为address下的字段名:
<input className={style.bodylessInput} placeholder=" " type="text" maxLength={30} name="addressLine1" value={formData.address.addressLine1} onChange={handleChange} /> <!-- city/state/zip的输入框name分别设为"city"、"state"、"zip" -->
- 修改
handleChange函数,判断当前字段是否属于address对象,再构造对应的更新数据:
function handleChange(event) { const { name, value } = event.target; // 定义address下的所有字段 const addressFieldNames = ['addressLine1', 'city', 'state', 'zip']; if (addressFieldNames.includes(name)) { // 更新address对象,保留原有字段并修改当前字段 setFormData({ name: 'address', value: { ...formData.address, [name]: value } }); } else { // 非address字段,按原有逻辑更新顶层属性 setFormData({ name, value }); } }
formReducer无需修改,保持原有逻辑即可。
内容的提问来源于stack exchange,提问作者user11631308
相关产品推荐
相关产品推荐

