Warning: Instance created by `useForm` is not connect to any Form element

Viewed 16352

I have an application where built a form and i want to setDefaultValue for the form. I used: const [form] = Form.useForm();. My form tag looks like bellow:

<Form form={form} name="basic" onFinish={onFinish} onFinishFailed={onFinishFailed}>

And i try to set defaultValue:

form.setFieldsValue({
  name: object.name,
});

Here i get the next warning: Warning: Instance created by `useForm` is not connect to any Form element. Forget to pass `form` prop?

I saw many answers with this topic, but they solved the issue by adding form={form}. In my case it doesn't work. What could be the issue?

10 Answers

Before Modal opens, children elements do not exist in the view. You can set forceRender on Modal to pre-render its children. source

  <Modal forceRender visible={visible} onOk={okHandler} onCancel={closeHandler}>
    <Form form={form}>
      <Form.Item name="user">
        <Input />
      </Form.Item>
    </Form>
  </Modal>

I think it's warning because you call form method

form.setFieldsValue({
    note: text.note,
    gender: text.gender
});

before form instance patch on the form component <Form form={form}.... So I think you should call it when componentDidMount

useEffect(() => {
    form.setFieldsValue({ note: "2", gender: "demo" });
    setText({ note: "2", gender: "demo" });
}, []);

or

useEffect(() => {
    setText({ note: "2", gender: "demo" });
}, []);

useEffect(() => {
    form.setFieldsValue({ note: text.note, gender: text.gender });
}, [text]);

I fixed the problem by using form.__INTERNAL__.name as this will be undefined if the instance created by useForm is not connected to any form element (remember to set name property on your form element or form.__INTERNAL__.name will be undefined in both cases).

const form = useForm();
if (form.__INTERNAL__.name) {
   // do form logic here
   form.setFieldsValue({name: "Ahmed Hamed"});
}

...
<Form name="myForm" form={form}>...</Form>
...
setTimeout(function () {
      form.setFieldsValue(node);
    },0);

This is how I solved it

The following helped me.

I deleted the code:

const [form] = Form.useForm();

The assignment of initial values is done like this:

<Form 
  name="basic"
  onFinish={onFinish}
  onFinishFailed={onFinishFailed}
  initialValues={{
    name: object.name,
  }}
>

I also adopted this solution

setTimeout(function () {
  form.setFieldsValue(node);
},0);

not beutifull but this way solves, instead I wasn't able to intercept with useEffect. a bit of my current code

const EditModal = () => {
const [form] = Form.useForm();
const [visible,setVisible] = useState(false);

[...]

EditModal.open = (data) => {
    setTimeout(function () {
        form.setFieldsValue({ title: data.title, des: data.des, });
    },0);  
    setVisible(true);
} 

return <>... <Form form={form}

What eventually helped me was to put the modal inside the actual Form tag that is placed in the component. This way, I wouldn't depend on forceRender and strange behaviours related.

<Form form={form}>
    <Modal visible={isModalVisible}>
        <Form.Item label="something">
            <Input />
        </Form.Item>
    </Modal>
</Form>

My case was because Form was conditionally rendered, like:

// ...
useEffect(() => {
  form.setFieldsValue({ name: collectionName }) // this warns
}, [collectionName])

if (conditionalInitiallyTrue) {
  return <span>None</span>
}
return (
  <Form
    form={form}
    initialValues={...}
    onFinish={...}
  >
)

How did I solve it: using ref.

// ...
const formRef = useRef(null) // set initial ref as null

useEffect(() => {
  if (formRef.current) // verify ref link with current
    form.setFieldsValue({ name: collectionName })
}, [collectionName, conditionalInitiallyTrue, form]) // run useEffect when formRef updates

if (conditionalInitiallyTrue) {
  return <span>None</span>
}
// set ref in Form (fomRef.current will update as soon this appears)
return (
  <Form
    form={form}
    initialValues={...}
    onFinish={...}
    ref={formRef}
  >
}

Not sure if this is helpful but, let me know.

I found out this problem came when you call form instance before component was rended, just check useEffect or something else was call form before component was render

Related