`useForm` is not connected to any Form element. Forget to pass `form` prop?

自己封装了一个组件:CUDataModal

代码如下:
components/CUDataModal.tsx

import React, { useEffect } from 'react';
import { Modal, Form, Input, Button } from 'antd';
import { Rule } from 'antd/es/form';
import { useForm } from 'antd/es/form/Form';

// 删除 CSS 导入
// 删除 import './CUDataModal.css';

interface Field {
  name: string;
  label: string;
  type: string;
  rules?: unknown[];
}

interface CUDataModalProps {
  open: boolean;
  onClose: () => void;
  onSubmit: (values: unknown) => void;
  mode: 'create' | 'update';
  fields: Field[];
  initialValues?: unknown;
}

const CUDataModal: React.FC<CUDataModalProps> = ({ open, onClose, onSubmit, mode, fields, initialValues }) => {
  const [form] = useForm();

  useEffect(() => {
    if (form) {
      form.resetFields();
    }
  }, [form]);

  useEffect(() => {
    if (mode === 'update' && initialValues) {
      form.setFieldsValue(initialValues);
    } else {
      form.resetFields();
    }
  }, [mode, initialValues, form]);

  const handleOk = () => {
    form
      .validateFields()
      .then(values => {
        onSubmit(values);
        onClose();
      })
      .catch(info => {
        console.log('Validate Failed:', info);
      });
  };

  return (
    <Modal
      open={open}
      title={mode === 'create' ? 'Create Data' : 'Update Data'}
      onCancel={onClose}
      centered
      // 删除 className 和 style 属性
      footer={[
        <Button key="back" onClick={onClose}>
          Cancel
        </Button>,
        <Button key="submit" type="primary" onClick={handleOk}>
          Confirm
        </Button>,
      ]}
    >
      <Form form={form} layout="vertical">
        {fields.map(field => (
          <Form.Item
            key={field.name}
            name={field.name}
            label={field.label}
            rules={field.rules as Rule[]}
          >
            {field.type === 'text' && <Input />}
            {/* 可以根据需要添加更多类型的输入框 */}
          </Form.Item>
        ))}
      </Form>
    </Modal>
  );
};

export default CUDataModal;

components/CUDataModal.css

.custom-modal {
  display: flex;
  align-items: center;
  justify-content: center;
}

.custom-modal .ant-modal-content {
  top: 0;
  padding: 0;
}

调用执行:
App.tsx

import React, { useState } from 'react';
import { Button } from 'antd';
import CUDataModal from './components/CUDataModal';

const App: React.FC = () => {
  const [ModalOpen, setModalOpen] = useState(false);
  const [mode, setMode] = useState<'create' | 'update'>('create');
  const [initialValues, setInitialValues] = useState<unknown>(null);

  const fields = [
    { name: 'name', label: 'Name', type: 'text', rules: [{ required: true, message: 'Please input the name!' }] },
    { name: 'age', label: 'Age', type: 'text', rules: [{ required: true, message: 'Please input the age!' }] },
    // 可以根据需要添加更多字段
  ];

  const handleCreate = () => {
    setMode('create');
    setInitialValues(null);
    setModalOpen(true);
  };

  const handleUpdate = () => {
    setMode('update');
    setInitialValues({ name: 'John Doe', age: 30 });
    setModalOpen(true);
  };

  const handleSubmit = (values: unknown) => {
    console.log('Submitted values:', values);
  };

  return (
    <div>
      <Button type="primary" onClick={handleCreate}>
        Create Data
      </Button>
      <Button type="default" onClick={handleUpdate} style={{ marginLeft: 8 }}>
        Update Data
      </Button>
      <CUDataModal
        open={ModalOpen}
        onClose={() => setModalOpen(false)}
        onSubmit={handleSubmit}
        mode={mode}
        fields={fields}
        initialValues={initialValues}
      />
    </div>
  );
};

export default App;

但是现在有1个问题:

想要点击时候,从中间弹出,但是这里是从左边弹出:

image.png

但是代码是定义了Modal的centered属性的,不知道为何还是这样弹出:
image.png

阅读 697
avatarAI BotBETA

问题1解答

关于 useForm 组件的警告 "Instance created by useForm is not connected to any Form element. Forget to pass form prop?",这个问题通常发生在 Form 组件没有正确地通过 form 属性接收 useForm 钩子返回的表单实例。在你的代码中,这个连接是正确设置的:

<Form form={form} layout="vertical">
  ...
</Form>

但是,警告可能仍然出现,因为 useEffect 钩子中的 form.resetFields();form.setFieldsValue(initialValues); 调用可能在 Form 组件渲染到 DOM 之前就已经执行了。由于此时 Form 组件尚未挂载,因此 form 实例可能还没有与 DOM 中的 Form 元素关联。

解决方案
确保这些表单操作在 Form 组件已经挂载到 DOM 后执行。这通常不是问题,因为 React 的渲染流程会自动处理这些依赖关系。然而,你可以通过将 form 实例的引用放在一个依赖数组中,但这在当前的 useEffect 钩子中已经是这样做的。另一个可能是检查是否有其他地方的代码(未在此代码中显示)干扰了 Form 组件的渲染或 useForm 钩子的使用。

如果问题依旧存在,尝试将 useEffect 钩子中的代码移到一个函数中,并在 Form 组件的 onMountonReady 事件中调用该函数(尽管 Ant Design 的 Form 组件没有直接的 onMountonReady 事件,但这是一个概念上的解决方案)。

问题2解答

关于 Modal 组件从左边弹出而不是中间弹出的问题,尽管你已经设置了 centered 属性,但可能还有其他 CSS 样式影响了 Modal 的布局。

解决方案

  1. 检查全局样式:确保没有其他全局 CSS 规则(如 margin, padding, position 等)影响到 Modal 组件的布局。
  2. 确保没有样式覆盖:检查你的组件和全局样式文件,确认没有样式覆盖了 Modal 的默认样式。
  3. 更新 Ant Design 版本:确保你使用的 Ant Design 版本没有已知的与 Modal 居中相关的 bug。
  4. 使用 CSS 覆盖:如果其他方法都无效,你可以尝试使用更具体的 CSS 选择器来强制 Modal 居中。例如,在你的 CUDataModal.css 文件中添加:

    .ant-modal {
      top: 50% !important;
      transform: translateY(-50%) !important;
    }

但请注意,这种方法可能会影响到应用中其他地方的 Modal 组件。

  1. 检查父元素:确保 Modal 的父元素(如果有的话)没有设置影响其位置的样式,如 overflowposition 属性。
  2. 清除缓存:有时候,浏览器缓存的旧 CSS 或 JavaScript 文件可能导致显示问题。尝试清除缓存或使用无痕模式查看页面。
1 个回答

报错应该是未点击open的时候报错的吧,可能是初始化modal的时候就执行了第一个useEffect,但是这个时候modal没渲染,绑不到实例就报错了

  useEffect(() => {
    if (open) {
      form.resetFields();
    }
  }, [open, form]);

或者试试modal的forceRender方法,官网FAQ链接

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏