如何将对象设置为表单值以与 Material UI 做出反应?

Posted

技术标签:

【中文标题】如何将对象设置为表单值以与 Material UI 做出反应?【英文标题】:How to set objects as form values in react with Material UI? 【发布时间】:2021-03-21 00:22:02 【问题描述】:

我目前正在尝试使用 React 和 Material UI 构建一个表单,我的最终有效负载必须如下所示:


  title: title,
  quadrants: 
    0:  name: quadrantOne ,
    1:  name: quadrantTwo ,
    2:  name: quadrantThree ,
    3:  name: quadrantFour 
  

我的表单的对应部分(包括初始值)的结构如下:

const initialValues = 
  title: '',
  quadrants: ,
;

const [values, setValues] = useState(initialValues);

const handleInputChange = (e: any) => 
  const  name, value  = e.target;
  setValues(
    ...values,
    [name]: value
  );
;

return (
    <Form>
        <Grid item xs=12 sm=12>
          <Input
            name="title"
            label="Title"
            value=initialValues.title
            onChange=handleInputChange
          />
        </Grid>
        <Grid item xs=12 sm=6>
          <Input
            name="quadrant-one"
            label="Quadrant 1"
            value=initialValues.quadrants
            onChange=handleInputChange
          />
        </Grid>
        <Grid item xs=12 sm=6>
          <Input
            name="quadrant-two"
            label="Quadrant 2"
            value=initialValues.quadrants
            onChange=handleInputChange
          />
        </Grid>
    </Form>
)

这样,我的输入框是这样的,这样我就不能在字段中输入任何东西了::

但是,如果我在字段中输入一些内容(该条目不可见),那么我会得到以下有效负载:


  title: "Test"
  quadrants: 
  quadrant-one: "[object Object]"
  quadrant-two: "[object Object]"

条目不嵌套在“象限”对象中,但条目以相应表单元素的名称出现在有效负载中(如第一象限、第二象限……)。

我在这里做错了什么,我该如何解决?

【问题讨论】:

您将对象作为值传递 -->value=initialValues.quadrants,也许应该是 value=initialValues.quadrants[0].name 我知道传递对象是错误的。有趣的是, quadrants 属性是一个对象而不是数组。所以我不能使用 initialValues.quadrants[0].name.. 可以,可以使用initialValues.quadrants[0],试试看。 @lissettdm 当我使用 values.quadrants[0].name 时,它​​说:“TypeError: Cannot read property 'name' of undefined”。我是否需要更改象限的结构: inside initialValues? 【参考方案1】:

试试这个修复:-

input valuevalue=initialValues.title 更改为 value=values.title。由于您已经将 initialValues 设置为 state valuesonChange 事件仅反映在 state values 被更新为 setValues。不直接在 const initialValues 上(对其余的输入执行相同操作 - 仅使用 values state 的输入)

functionhandleTitleChange()

const handleTitleChange = (e: any) => 
  const  name, value  = e.target;
  
  setValues(
    ...values,
    [name]: value
  );
;
functionhandleQuadrantChange()
const handleQuadrantChange = (e: any) => 
  const  name, value  = e.target;
  
  setValues(
    ...values,
    quadrants: 
      ...values.quadrants,
      [name]: value
    
  );
;

【讨论】:

好的,但问题与initialState的使用无关,而是对象象限内对象值的设置:。 我只是在上面更新了我的答案。试一试 实际上,这正是我想要避免的。功能完全相同,因此它们实际上是重复的。此外,这也不能解决我的问题。像这样,我不能在象限中​​嵌套其他对象: 对象,如我的问题中所述。在顶部检查我需要的最终有效载荷。【参考方案2】:

您收到[Object Object] 因为 initialValues.quadrants 是一个对象,我假设您正在尝试设置 initialValues.quadrants[0].name,但初始值 initialValues.quadrants[0] 未定义

您需要应用一些更改。我建议您为象限输入定义一个自定义属性(数据索引),这样在输入更改时您可以更新正确的对象。同样对于象限输入,您可以定义一个函数来获取值,因为在第一次渲染时它的值是未定义的:

const initialValues = 
    title: "",
    quadrants: 
  ;

  const [values, setValues] = useState(initialValues);

  const handleInputChange = e => 
    const  name, value  = e.target;
    const dataIndex = Number(e.target.getAttribute("data-index"));
    setValues(prev => 
      if (name === "title") 
        return 
          ...prev,
          [name]: value
        ;
       else 
        return 
          ...prev,
          quadrants: 
            ...prev.quadrants,
            [dataIndex]:  name: value 
          
        ;
      
    );
  ;

  const getValue = prop => 
    const value = values.quadrants[prop] ? values.quadrants[prop].name : "";
    return value;
  ;

return (
    <Form>
        <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="quadrant-one"
            label="Quadrant 1"
            data-index="0"
            value=getValue(0)
            onChange=handleInputChange
          />
        </Grid>
        <Grid item xs=12 sm=6>
          <Input
            name="quadrant-two"
            label="Quadrant 2"
            data-index="1"
            value=getValue(1)
            onChange=handleInputChange
          />
        </Grid>
    </Form>
)

【讨论】:

有效!谢谢你。也许我会为我的象限创建一个自己的 changeHandler,这样我就可以删除 setValues 中的 if。 是的,我认为划分handleInputChange函数要干净得多

以上是关于如何将对象设置为表单值以与 Material UI 做出反应?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 div 以与 Drawer React Material UI 相同的宽度粘在 Drawer 的底部?

ReactJS + Material-UI:如何使用 Material-UI 的 <DatePicker> 将当前日期设置为默认值?

使用material-ui为redux-form设置initialValues无效

如何将 HMTL 属性设置为 Material UI InputProps?

使用自动映射器设置属性值以与其他 2 个组合

如何在 Material-UI 中为对话框设置高度?