NextJS+TypeScript写入Firestore嵌套对象(Map)的表单输入问题
解决React嵌套对象状态更新问题
你遇到的错误是因为在对象字面量中直接使用adress.street作为键名是非法的JavaScript语法。要正确更新嵌套对象的属性,需要逐层展开并重构对象,同时保留未修改的属性。
单个嵌套属性的修正写法
以更新adress.street为例,修改onChange逻辑如下:
<TextInput onChange={(e: React.ChangeEvent<HTMLInputElement>) => setFormInput({ ...formInput, // 保留外层所有原有属性 adress: { ...formInput.adress, // 保留adress对象的其他属性 street: e.target.value // 更新目标属性 } }) } type="text" name="street-address" id="street-address" autoComplete="street-address" value={formInput.adress.street} // 必须绑定value实现双向同步 />
其他嵌套属性的示例
针对数字类型的adress.zip和phone对象的属性,按照相同模式处理:
// 更新adress.zip(数字类型需转换) <TextInput onChange={(e) => setFormInput({ ...formInput, adress: { ...formInput.adress, zip: parseInt(e.target.value, 10) } }) } type="number" name="zip" id="zip" value={formInput.adress.zip.toString()} /> // 更新phone.phoneNumber <TextInput onChange={(e) => setFormInput({ ...formInput, phone: { ...formInput.phone, phoneNumber: e.target.value } }) } type="tel" name="phoneNumber" id="phoneNumber" value={formInput.phone.phoneNumber} />
优化:封装通用更新函数
如果嵌套层级多或需要更新多个属性,可以封装一个通用函数减少重复代码:
const updateNestedField = (fieldPath: string, value: any) => { setFormInput(prevState => { const keys = fieldPath.split('.'); const updatedState = {...prevState}; let currentLevel = updatedState; // 逐层遍历嵌套路径,复制每一层对象 for (let i = 0; i < keys.length - 1; i++) { currentLevel[keys[i]] = {...currentLevel[keys[i]]}; currentLevel = currentLevel[keys[i]]; } // 设置目标属性值 currentLevel[keys[keys.length - 1]] = value; return updatedState; }); };
使用时只需传入属性路径和值:
<TextInput onChange={(e) => updateNestedField('adress.street', e.target.value)} type="text" name="street-address" id="street-address" autoComplete="street-address" value={formInput.adress.street} />
内容的提问来源于stack exchange,提问作者maxplex
相关产品推荐
相关产品推荐

