antd将嵌套表单的对话框组件化,实现编辑功能

本文通过实战案例,探讨了在React应用中使用antd组件库时,如何正确地将数据绑定到嵌套表单的对话框组件中。文章详细记录了作者在解决表单数据不显示问题时的调试过程及解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

当使用对话框提交修改表单时,需要在输入框 Input 显示需要修改的数据,但使用 value 绑定对应数据,并未生效,具体代码如下:

function YwkclbEdit (props) {
	....
	const editData = props.data;
	....
}
<Form.Item
  name='hzxm'
  label='患者姓名'
>
  <Input placeholder="请输入患者姓名"
         value={editData.name} />
</Form.Item>

结果,在控制台输出数据时,可以发现 editData 是有对应数据的,但对话框却没有显示对应数据。
在这里插入图片描述

测试一

如果不是 Input 组件和数据的问题,那么应该是嵌套了 Form 表单引起的。

因此,单独测试下,将 Input 单独提取出表单外。

<Input placeholder="请输入患者ID" value={editData.name} />
<Form
  ref={ywkcEditForm}
  name='ywkcEditForm'
  size="small"
  {...layout}
>
  <Row justify="start" className="ywgllbAddFormItem">
    <Col span="24" key="a1">
      <Form.Item
        name='hzid'
        label='患者ID'
      >
        <Input placeholder="请输入患者ID" value={editData.name} />
      </Form.Item>
    </Col>
  </Row>

结果如下,的确是嵌套表单引起的。

在这里插入图片描述

重新回顾Form组件相关内容,发现:

被设置了 name 属性的 Form.Item 包装的控件,表单控件会自动添加 value(或 valuePropName 指定的其他属性) onChange(或 trigger 指定的其他属性),数据同步将被 Form 接管,这会导致以下结果:

1、你不再需要也不应该用 onChange 来做数据收集同步(你可以使用 Form 的 onValuesChange),但还是可以继续监听 onChange 事件。

2、你不能用控件的 value 或 defaultValue 等属性来设置表单域的值,默认值可以用 Form 里的 initialValues 来设置。注意 initialValues 不能被 setState 动态更新,你需要用 setFieldsValue 来更新。

3、你不应该用 setState,可以使用 form.setFieldsValue 来动态改变表单值。
在这里插入图片描述

测试二

从文档解释可以发现错误在于数据同步被Form接管,因此,要将需要同步的数据交给Form使用(ps.虽然有除去name属性的方法,但先且按文档说明使用):

function YwkclbEdit (props) {
  const ywkcEditForm = React.createRef();
  const editData = props.data;
  ywkcEditForm.current.setFieldsValue({  // 错误处
    hzid: editData.name
  })
  
  ...
  
  <Form
    ref={ywkcEditForm}
    name='ywkcEditForm'
    size="small"
    {...layout}
  >
    <Row justify="start" className="ywgllbAddFormItem">
      <Col span="24" key="a1">
        <Form.Item
          name='hzid'
          label='患者ID'
        >
          <Input placeholder="请输入患者ID"/>
        </Form.Item>
      </Col>
    </Row>

	...
}

想法很美好,现实很骨感,直接出现错误:

TypeError: Cannot read property ‘setFieldsValue’ of null

没有对应属性,容易发现是表单创建失败

继续查看文档,由于我们使用的函数组件,对应表单数据交互应该使用

Form.useform

在这里插入图片描述

测试三

根据文档提示,合理使用,成功实现数据交互。

function YwkclbEdit (props) {
  const [ ywkcEditForm ] = Form.useForm(); // useForm() 返回的是表单数组,因此需要[]
  const editData = props.data;
  ywkcEditForm.setFieldsValue({
    hzid : editData.name,
 })
 
 ...
<Form
  form={ywkcEditForm}  // 修改处
  name='ywkcEditForm'
  size="small"
  {...layout}
>
  <Row justify="start" className="ywgllbAddFormItem">
    <Col span="24" key="a1">
      <Form.Item
        name='hzid'
        label='患者ID'
      >
        <Input placeholder="请输入患者ID"/>
      </Form.Item>
    </Col>
  </Row>
 
 ...
}

演示效果如下,但是却出现了

Warning: Instance created by useForm is not connected to any Form element. Forget to pass form prop?
Uncaught SyntaxError: Unexpected token ‘<’

在这里插入图片描述

测试四

详细查看文档小字部分,发现在 Modal 中调用 Form 时,因为Modal还初始化,导致 Form 实例没有绑定表单,根据文档给 Modal 添加forceRender 属性,可以解决该警告。

在这里插入图片描述
在为Modal添加了 forecRender 属性后,选择任意数据后,会发现如下警告:

Warning: Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state.

报错是由于引用的子组件通过props进行传递,传递的过程中 Modal 实际上已经处于render阶段了 ,render 还没结束时将数据传入会触发state 改变,在这个阶段如果你再改变这个state值的话就会报这个错。因此,不要在render的时候改变state就可以解决问题。

考虑到父组件传入的数据为只读,又需要通过异步操作避免render时本地state变动的问题,要避免直接传入父组件数据来为本地state赋值,同时,考虑到多用户情况,列表数据可能已经被修改,应该采用axios请求服务器发送对应ID的数据,保证数据实时性,代码如下:

  // 子组件通过获取父组件传入的editId,向服务器申请对应数据并赋值
  const searchById = (id) => {
    console.log(id);
    Conn.getYwkcById(id)
      .then(res => {
        ywkcEditForm.setFieldsValue({hzid: res.hzid, ywmc: res.ywmc,ywpp: res.ywpp, ywsl: res.ywsl})
      })
      .catch((err) => {
        console.log(err);
      })
  };
  
  searchById(props.editId);

结果很成功,先前出现的警告消失了,而且数据也能顺利交互。

总结

测试到此告一段落了,关于React、antd如何将嵌套表单的对话框组件化、实现数据交互作出了实践测试。

另外,Antd的说明文档非常重要的,遇到问题往往可以先查看说明文档,只要找到了对应的错误,往往会有成熟的解决方案。

引用

https://www.cnblogs.com/banyouxia/p/13188698.html

https://blog.youkuaiyun.com/estherlxy/article/details/106145389

https://ant.design/components/modal-cn/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值