You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Antd Modal内使用Form出现useForm警告及重新打开后数据不更新问题

问题根因

你遇到的两个异常都是组件定义方式和状态管理逻辑错误导致的,具体问题如下:

  • useForm实例警告:你把包含Form的EventContent组件定义在点击事件回调sendeventdata内部,首次渲染App的时候Form组件根本没有挂载,useForm实例找不到绑定的Form元素就会抛出警告,同时你给Modal传的form属性完全无效,Antd的Modal组件本身不支持这个参数。
  • 弹窗重开数据不更新:你没有用React状态存储点击传入的事件数据,且Form的initialValues仅在组件首次挂载时生效,后续打开弹窗时没有主动更新表单值,就算加了destroyOnClose,因为组件嵌套定义的逻辑问题,新的事件数据也没法正确传入表单。

修复方案

第一步:调整组件定义位置,不要嵌套声明组件

组件嵌套在其他函数/组件内部会导致每次父组件渲染时都生成新的组件实例,状态无法正常同步,把EventContent和MyModal都挪到App组件外部定义,通过props传递需要的参数。

第二步:新增状态存储弹窗和事件数据

在App组件顶层声明状态管理弹窗显隐和当前选中的事件数据,修复后的完整参考代码如下:

import { useState, useEffect } from 'react';
import { Form, Modal, Button, DatePicker, TimePicker } from 'antd';
import moment from 'moment';

// 把EventContent挪到外部定义
const EventContent = ({ form, event, l, preferredDateFormat, setValueDate, onUpdate, handleDelete }) => {
  // 表单打开时主动赋值,不受initialValues仅首次生效的限制
  useEffect(() => {
    if (event) {
      form.setFieldsValue({
        datePicker: moment(event.start),
        timeRangePicker: [moment(event.start), moment(event.end)],
      })
    }
  }, [event, form])

  return (
    <div>
      <Form
        form={form}
        labelAlign="left"
        layout="vertical"
      >
        <Form.Item name="datePicker" label={l.availability.date}>
          <DatePicker className="w-100" format={preferredDateFormat} onChange={setValueDate} />
        </Form.Item>
        <Form.Item name="timeRangePicker" label={l.availability.StartToEnd}>
          <TimePicker.RangePicker className="w-100" format="HH:mm" />
        </Form.Item>
        <span className="d-flex justify-content-end">
          <Button
            className="ml-1 mr-1"
            onClick={() => {
              form
                .validateFields()
                .then((values) => {
                  onUpdate(values)
                  form.resetFields()
                })
                .catch((info) => {
                  console.log('Validate Failed:', info)
                })
            }}
          >
            {l.availability.updateBtn}
          </Button>
          <Button danger className="ml-1 mr-1" onClick={handleDelete}>
            Delete
          </Button>
        </span>
      </Form>
    </div>
  )
}

// 把MyModal也挪到外部定义
const MyModal = ({ visible, title, onClose, children }) => {
  return (
    <Modal
      onCancel={onClose}
      title={title}
      visible={visible}
      footer={null}
      destroyOnClose
    >
      {children}
    </Modal>
  )
}

function App () {
  const [form] = Form.useForm();
  // 新增状态管理弹窗和事件数据
  const [modalVisible, setModalVisible] = useState(false);
  const [currentEvent, setCurrentEvent] = useState(null);
  const [modalTitle, setModalTitle] = useState('');

  const sendeventdata = (e) => {
    // 点击时存储事件数据和弹窗配置,打开弹窗
    setCurrentEvent(e.event);
    setModalTitle(e.title);
    setModalVisible(true);
  }

  const handleModalClose = () => {
    setModalVisible(false);
    setCurrentEvent(null);
    form.resetFields();
  }

  // 剩余业务逻辑:setValueDate、onUpdate、handleDelete、多语言配置l、日期格式preferredDateFormat等自行补充

  return (
    <div>
      <MyModal
        visible={modalVisible}
        title={modalTitle}
        onClose={handleModalClose}
      >
        {currentEvent && <EventContent
          form={form}
          event={currentEvent}
          l={l}
          preferredDateFormat={preferredDateFormat}
          setValueDate={setValueDate}
          onUpdate={onUpdate}
          handleDelete={handleDelete}
        />}
      </MyModal>
      <Button onClick={sendeventdata}>打开弹窗</Button>
    </div>
  )
}

核心修复点说明

  • 移除了Modal上无效的form属性,仅在Form组件上绑定form实例,且保证Form组件挂载时form实例已经初始化完成,不会再抛出未关联的警告
  • 弹窗打开时通过form.setFieldsValue主动更新表单值,每次打开弹窗都会用最新的事件数据填充表单
  • 关闭弹窗时主动重置表单,清空缓存的旧数据

内容的提问来源于stack exchange,提问作者WildThing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 17:57:00