如何在React与Material UI中正确设置嵌套对象作为表单值?
表单问题分析与修复方案
咱们先拆解下你遇到的两个核心问题,然后逐个解决:
问题根源
1. 输入框无法输入 + 显示[object Object]
你现在所有输入框的value都绑定了初始值initialValues,而不是组件状态里的values——这就导致输入时状态更新了,但UI不会跟着刷新,看起来像无法输入。另外,象限输入框直接绑了initialValues.quadrants(一个空对象),浏览器会把对象转成字符串,所以显示成[object Object]。
2. 表单值无法正确嵌套到quadrants对象
你的handleInputChange只处理了顶层属性(比如title),但象限输入框的name是quadrant-one这种自定义名称,没法自动映射到quadrants里的0、1这些索引键,所以提交时这些值会变成根对象的单独键,而quadrants还是空的。
修复方案
我给你整理了完整的修复代码,咱们一步步看改动点:
第一步:修正初始值结构
先把quadrants初始化好每个索引的name字段,避免后续读取时出现undefined:
const initialValues = { title: '', quadrants: { 0: { name: '' }, 1: { name: '' }, 2: { name: '' }, 3: { name: '' }, }, };
第二步:重写handleInputChange支持嵌套更新
针对象限的输入,我们需要更新quadrants里对应索引的子对象,而不是直接在根对象加键:
const handleInputChange = (e: any) => { const { name, value } = e.target; // 处理标题这类顶层属性 if (name === 'title') { setValues(prev => ({ ...prev, title: value })); return; } // 处理象限输入:name直接对应quadrants的索引(0-3) const quadrantIndex = name; setValues(prev => ({ ...prev, quadrants: { ...prev.quadrants, [quadrantIndex]: { ...prev.quadrants[quadrantIndex], name: value, }, }, })); };
第三步:修正输入框的绑定
把所有输入框的value改成绑定状态里的values,并且给象限输入框设置对应索引的name:
return ( <Form onSubmit={(e) => { e.preventDefault(); console.log('最终请求负载:', values); // 可以在这里验证格式 }}> <Grid item xs={12} sm={12}> <Input name="title" label="Title" value={values.title} onChange={handleInputChange} /> </Grid> <Grid item xs={12} sm={6}> <Input name="0" label="Quadrant 1" value={values.quadrants[0].name} onChange={handleInputChange} /> </Grid> <Grid item xs={12} sm={6}> <Input name="1" label="Quadrant 2" value={values.quadrants[1].name} onChange={handleInputChange} /> </Grid> {/* 补充Quadrant 3和4的输入框 */} <Grid item xs={12} sm={6}> <Input name="2" label="Quadrant 3" value={values.quadrants[2].name} onChange={handleInputChange} /> </Grid> <Grid item xs={12} sm={6}> <Input name="3" label="Quadrant 4" value={values.quadrants[3].name} onChange={handleInputChange} /> </Grid> <Grid item xs={12} mt={2}> <button type="submit">提交表单</button> </Grid> </Form> );
验证效果
现在提交表单时,你会得到完全符合预期的请求负载:
{ title: "Test", quadrants: { 0: { name: "你的象限1内容" }, 1: { name: "你的象限2内容" }, 2: { name: "你的象限3内容" }, 3: { name: "你的象限4内容" } } }
输入框也能正常输入,不会再显示[object Object]啦~
内容的提问来源于stack exchange,提问作者Codehan25
相关产品推荐
相关产品推荐

