Ant-design: `useForm`によって作成されたインスタンスは、どのForm要素にも接続されていません。`form`propを渡すのを忘れていますか?明らかに、例に従います。

作成日 2020年02月23日  ·  56コメント  ·  ソース: ant-design/ant-design

  • []このリポジトリの問題を検索し

複製リンク

https://next.ant.design/components/form-cn/#components -form-demo-form-in-modal

再現する手順

useFormを直接使用するだけです。ポップアップレイヤーの例を参照します。

const CollectionCreateForm =({onCancel})=> {
const [form] = Form.useForm();
form.setFieldsValue({
categoryName:caseDetail.categoryName、
});
戻る (
可視= {可視}
maskClosable = {false}
title = "プロジェクトの基本情報を変更する"
okText = "OK"
cancelText = "キャンセル"
onCancel = {onCancel}
onOk = {()=> {

.validateFields()
.then(values => {
form.resetFields();
onCreate(values);
})
.catch(info => {
window.console.log( '検証に失敗しました:'、info);
});
}}
>>

form = {form}
layout = "vertical"
name = "form_in_modal"
initialValues = {{
修飾子: 'public'、
}}
>>



name = "title"
label = "Title"
ルール= {[
{{
必須:true、
メッセージ:「コレクションのタイトルを入力してください!」、
}、
]}
>>







);
};

何が期待されますか?

このuseFormを普通に使えるようにしたいだけです

実際に何が起こっているのですか?

index.js:1警告: useFormによって作成されたインスタンスはどのForm要素にも接続されていません。 formプロパティを渡すのを忘れていますか?
CollectionCreateFormで...。

const [form] = Form.useForm();
form.setFieldsValue({
categoryName:caseDetail.categoryName、
});

form = {form}
layout = "vertical"
name = "form_in_modal"
initialValues = {{
修飾子: 'public'、
}}
>>

|環境|情報|
| --- | --- |
| antd | 4.0.0-rc.5 |
|反応| 16.8.6 |
|システム| mac10.15.3 |
|ブラウザ|クローム|


公式サイトから直接来たのですが、どこでもこのエラーが報告されて、言葉が出ませんでした。

❓FAQ

最も参考になるコメント

解決しました。ドロワーで、getContainer = {false}を使用すると解決できます。モーダルも同じだと思います。
ドロワーでgetContainer = {false}を使用します。モーダルでも同じ問題が発生するはずです。試してみてください。

全てのコメント56件

image

こんにちは@LamTech。このリンクhttps://u.ant.design/codesandbox-reproまたは最小限のGitHubリポジトリをフォークして、オンライン複製を提供してください。 Need Reproduceラベルが付いた問題は、7日間アクティビティがない場合はクローズされます。 。

こんにちは@LamTech 、問題のトラブルシューティングを支援できるように、オンラインで作成するか、最小限のGitHubリポジトリを提供できます。 7日以内にフォローアップされない問題は自動的にクローズされます。

重要なのは、この方法を使用することですが、このエラー警告が報告され続けます。

ここでも同じ問題がありますが、codesandboxで再現できませんでした。

+1

forceRender属性をモーダルに追加します

setFieldsValueメソッドに遅延を追加できます

form.resetFields();を呼び出します。このように見えます。ローカルで開始されたhttp:// localhost :8001 / components / form-cn /#components-form-demo-form-contextが報告されます。

+1
この警告は、setFieldsValueを使用すると表示されますが、スムーズに表示できます。
useFormのインスタンスを渡しました

モーダルのフォームはデフォルトではレンダリングされません。 @ se7en00応答を参照して、モーダルにforceRenderを追加できます。または、モーダルが表示されてレンダリングが完了したら、 setFieldsValueresetFields呼び出します。

V4バージョン(関数コンポーネントにフォームが存在する)を使用すると、この問題に2日間悩まされ、ほとんどクラッシュしました(エラーが報告されましたが、使用には影響しませんでした)。最後に、https://ant.designを読みました。 /およびhttps://next。.ant.design/関数コンポーネントでのフォームの使用を発見し、クラスは関数コンポーネントを理解して区別する必要があります
useEffect(()=> {
return()=> {
form.resetFields();
};
})
代わりに破棄をトリガーするのは関数コンポーネント全体です()=> {....}(この時点でフォームが破棄されるかどうかはテストされていません)
ドキュメントの説明:destroyOnClose |閉じるときにモーダルの子要素を破棄します。デフォルトはfalseです。 forceRender |モーダルの必須レンダリング、デフォルトはfalse。
解決策:モーダルのforceRender = true、destroyOnClose = false、モーダルが破棄(クローズ)された場合、エラーは報告されません。フォームは内部コードの実行時に見つかりますが、入力制御IDの繰り返し警告が報告されます(エラーよりもエレガントです)。

同じ問題+1

コードにsetFieldsValueまたは他の関数が含まれている場合は、ノードがレンダリングされた後に呼び出します

useEffect(() => {
  form.setFieldsValue({
    id: 1
  })
}, [])

また

componentDidMount() {
  form.setFieldsValue({
    id: 1
  })
}

それは私の問題を解決しました

上記のどれでもこの問題を完全に解決することはできないと思います。フォームにフィールドがあるかどうかを示す属性をフォームに追加し、開発者自身に次のコードを実行するかどうかを決定させることができますか?

ここでも同じことが起こります

まだ修正されていませんか?

上記のすべての方法を試しましたが、機能しませんでした

モーダルのフォームはデフォルトではレンダリングされません。 @ se7en00応答を参照して、モーダルにforceRenderを追加できます。または、モーダルが表示されてレンダリングが完了したら、 setFieldsValueresetFields呼び出します。

ドロワーを使用すると、ドロワーにはforcerender APIがありますが、モーダルとは異なり、ドロワーのAPIは強制レンダリングではなく事前レンダリングであり、同じエラーが報告されるので、解決策はありますか?レンダリングが完了したと判断する方法は?

解決しました。ドロワーで、getContainer = {false}を使用すると解決できます。モーダルも同じだと思います。
ドロワーでgetContainer = {false}を使用します。モーダルでも同じ問題が発生するはずです。試してみてください。

useRefを使用してFormオブジェクトを保存し、フォームを使用する前にuseRefが存在するかどうかを判断できます。

ここで同じ問題。 フォームが割り当てられますが、失敗し続けます。

エフェクトでform.setFieldsValueを直接呼び出すと、forceRenterが追加され、Modalが再度開かれた場合でも、この警告が表示されます。一時的な解決策は、エフェクトでsetTimeout(()=> form.setFieldsValue、0)のみになります。

ドロワーの問題を解決するために、getContainer = {false}を使用しましたが、警告は報告されませんでした。同じ問題が発生した場合は、試してみて、フォームドキュメントに明確に記述できることを期待してください。

ありがとう、この方法は同じ問題を解決しました👍

あなたの方法は実行可能です、あなたは原理を説明できますか?

私の回避策は、 FormがレンダリングされたときにuseState ref作成し、フォームインスタンスを使用する前にref確認します。

interface FormModalProps {
  data?: RoleProps;
  visible: boolean;
  onCancel?: () => void;
  onSubmit?: (values: Store) => void;
  submitting: boolean;
}

const FormModal: React.FC<FormModalProps> = props => {
  const [form] = Form.useForm();
  const [formRef, setFormRef] = useState();  // <---- set the ref when Form Rendered

  const { data, onSubmit, onCancel, visible, submitting } = props;

  // reset Form when modal close
  useEffect(() => {
    if ( !props.visible && formRef) {  // <---- check ref before use the form instance
      form.resetFields();
    }
  }, [props.visible]);

  // fill Form when modal open
  useEffect(() => {
    if (visible && formRef) {   // <---- check ref before use the form instance
      form.setFieldsValue({
        ...data,
      });
    }
  }, [props.data]);

  // handle form onFinish
  const handleFormFinish = (values: Store) => {
    if (onSubmit) {
      onSubmit(values);
    }
  };

  // handle modal  ok
  const handleOk = () => {
    if (!form) return;
    form.submit();
  };

  return (
    <Modal
      title="Modal"
      confirmLoading={submitting}
      onOk={handleOk}
      onCancel={onCancel}
      visible={visible}
      width={640}
    >
      <Form ref={setFormRef} form={form} onFinish={handleFormFinish}>
        <Form.Item name="title" label="Title" >
          <Input />
        </Form.Item>
      </Form>
    </Modal>
  );
};

もう警告はありません!

英語で話し合うのは難しいですか?

setFieldsValueを使用する場合は、次のコードを置き換えてみてください(私の愚かな考え)。

<Modal        **destroyOnClose**      >
        <Form **initialValues={formValues}**>
        </Form>
</Modal>

私はそれを動かしました。
当初、私はantdコンポーネントを次のように呼んでいました。
<Form blabla >

次に、フォームコンポーネントにフォームプロップを追加しました-

<Form form={form} blabla >

ここで、{フォーム}はconst [form] = Form.useForm();から来ています

Doc(私がフォローしていたこと)-
https://ant.design/components/form/#components -form-demo-form-in-modal

あなたのケースは異なるかもしれません。

https://codesandbox.io/s/form-in-modal-to-create-ant-design-demo-xvcyv
同じ問題、どんな体でもそれを修正することができますか?

上記のlinxianxi、 https: //github.com/ant-design/ant-design/issues/21543#issuecomment-598515368を参照してください

モーダルできる

 <Modal
  destroyOnClose={false} 
  getContainer={false}
  forceRender
>

モーダルできる

 <Modal
  destroyOnClose={false} 
  getContainer={false}
  forceRender
>

ありがとう、モーダルにforceRenderプロップを追加してこの問題を修正しました

    const [form] = Form.useForm()

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

    </Form>```


         this did the trick for me.

私はそれを動かしました。
当初、私はantdコンポーネントを次のように呼んでいました。
<Form blabla >

次に、フォームコンポーネントにフォームプロップを追加しました-

<Form form={form} blabla >

ここで、{フォーム}はconst [form] = Form.useForm();から来ています

Doc(私がフォローしていたこと)-
https://ant.design/components/form/#components -form-demo-form-in-modal

あなたのケースは異なるかもしれません。

これは私にとってもそれを修正しました。 モーダルではなく、引き出しのフォームを使用していました

私にとっての秘密のコンボは次のとおりです。

useEffect(()=> {
if(フォーム&&表示){
if(現在){
setTimeout(()=> form.setFieldsValue({
...現在、
})、0);
} そうしないと {
form.resetFields();
}
}
}、 [現在]);

フォームコンポーネントへのモーダルおよびフォームプロップパスなしの同じエラー
https://codesandbox.io/s/basic-usage-ant-design-demo-6llbw?file=/index.js:1618-1661

フォームコンポーネントへのモーダルおよびフォームプロップパスなしの同じエラー
https://codesandbox.io/s/basic-usage-ant-design-demo-6llbw?file=/index.js:1618-1661

あなたのための修正: httpsindex.js

form.getVieldValueをForm.Itemコンポーネントに移動する必要があります

        <Form.Item
          shouldUpdate={(prevValues, curValues) =>
            prevValues.username !== curValues.username
          }
          noStyle
        >
          {() => <div>{form.getFieldValue("username")}</div>}
        </Form.Item>

別の方法は、useRef()を使用することです。

描画+フォーム。モーダル+フォームの場合、この方法が適用されます。

  1. forceRender = true、destroyOnClose = false。コンポーネントの1つでは機能しますが、他のコンポーネントでは機能しません。Form.Item間のリンクにより、コードは次のようになります。
const MyComp = React.memo(() => {
     const [form] = Form.useForm();
     const { getFieldValue } = form;
     const category = getFieldValue('category'); // It's the culprit
     return (/* something */);
})

適切な使用

<Form.Item
        noStyle
        shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender}
      >
        {({ getFieldValue }) => {
          return getFieldValue('gender') === 'other' ? (
            <Form.Item name="customizeGender" label="Customize Gender" rules={[{ required: true }]}>
              <Input />
            </Form.Item>
          ) : null;
        }}
 </Form.Item>

  1. forceRender = true、destroyOnClose = false。これは私のコンポーネントの1つでは機能しますが、他のコンポーネントでは機能しません。コンポーネント間のリンクのため、私のコードは次のようになっていることがわかりました
const MyComp = React.memo(() => {
     const [form] = Form.useForm();
     const { getFieldValue } = form;
     const category = getFieldValue('category'); // It's the culprit
     return (/* something */);
})

正しい使用方法

<Form.Item
        noStyle
        shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender}
      >
        {({ getFieldValue }) => {
          return getFieldValue('gender') === 'other' ? (
            <Form.Item name="customizeGender" label="Customize Gender" rules={[{ required: true }]}>
              <Input />
            </Form.Item>
          ) : null;
        }}
 </Form.Item>

これは、フォーム要素がレンダリングされていないために発生しますが、フォームに値を設定しました。 これはreactとフックに関する基本的な知識だと思います。setTimeoutを使用してレンダリングされたフォームを待機できます。

しかし、フォームの初期値を設定する最良の方法は

<Form
   initialValues={{ 
      name: 'Hafid',
      age: '35'
}}
onFinish={onFinish}
>

またはこの方法で

`` `js
const [values、setValues] = React.useState({})

React.useEffect(()=> {
// WebサービスまたはAPIからデータ値を取得します
// fecth(...)
if(values_from_api){
setValues(values_from_api);
}
}、[])

戻る<>

initialValues = {values}
onFinish = {onFinish}
>>

独自のカスタムフックでフォーム値を使用する必要がある場合はどうなりますか?
Ant 3では、次のようにしました。

const [updating, updateInfo] = useMyOwnCustomHookForSubmitAction(getFieldsValue());

const submitForm = () => {
   validateFields((err) => {
        if (!err) updateInfo();
   });
};

<Form>...</Form>

Ant 4でそのようにしようとすると、トピックからこのエラーが発生します。

const [form] = useForm();
const [updating, updateInfo] = useMyOwnCustomHookForSubmitAction(getFieldsValue());

const submitForm = () => {
   validateFields((err) => {
        if (!err) updateInfo();
   });
};

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

フォームはモーダルで、forceRender = true、destroyOnClose = falseが設定されています。 私は何が間違っているのですか?

V4バージョン(関数コンポーネントにフォームが存在する)を使用すると、この問題に2日間悩まされ、ほとんどクラッシュしました(エラーが報告されましたが、使用には影響しませんでした)。最後にhttps:// antを読みました
useEffect(()=> {
return()=> {
form.resetFields();
};
})
代わりに破棄をトリガーするのは関数コンポーネント全体です()=> {....}(この時点でフォームが破棄されるかどうかはテストされていません)
ドキュメントの説明:destroyOnClose |閉じるときにモーダルの子要素を破棄します。デフォルトはfalseです。 forceRender |モーダルの必須レンダリング、デフォルトはfalse。
解決策:モーダルのforceRender = true、destroyOnClose = false、モーダルが破棄(クローズ)された場合、エラーは報告されません。フォームは内部コードの実行時に見つかりますが、入力制御IDの繰り返し警告が報告されます(エラーよりもエレガントです)。

私もこの問題に遭遇しました、私はそれをこのように解決しました
モーダル構成forceRender |強制レンダリング
Modla形式では、name = {['modal'、 'cityCode']}
フィルタ形式のName = {['search'、 'cityCode']}またはname = 'cityCode'
このようにして、すべての警告を解決でき、一意でないID警告を持つFound2要素は報告されません⚠

useRefを使用してフォームの参照を参照し、formRef.currentのメソッドを使用できます。

const formRef = useRef()

return (<Form ref={formRef}>
  {
    (formRef.current && formRef.current.getFieldsValue('key') === 1) 
     &&
   (<Input />)
  }
</Form>)

モーダルのフォームはデフォルトではレンダリングされません。 @ se7en00応答を参照して、モーダルにforceRenderを追加できます。または、モーダルが表示されてレンダリングが完了したら、 setFieldsValueresetFields呼び出します。

属性forceRenderをModalに追加してもまったく役に立ちません

公式ブロックの例も警告しています

V4バージョン(関数コンポーネントにフォームが存在する)を使用すると、この問題に2日間悩まされ、ほとんどクラッシュしました(エラーが報告されましたが、使用には影響しませんでした)。最後にhttps:// antを読みました
useEffect(()=> {
return()=> {
form.resetFields();
};
})
代わりに破棄をトリガーするのは関数コンポーネント全体です()=> {....}(この時点でフォームが破棄されるかどうかはテストされていません)
ドキュメントの説明:destroyOnClose |閉じるときにモーダルの子要素を破棄します。デフォルトはfalseです。 forceRender |モーダルの必須レンダリング、デフォルトはfalse。
解決策:モーダルのforceRender = true、destroyOnClose = false、モーダルが破棄(クローズ)された場合、エラーは報告されません。フォームは内部コードの実行時に見つかりますが、入力制御IDの繰り返し警告が報告されます(エラーよりもエレガントです)。

このメソッドは解決できますが、三項演算子が表示されている場合、モーダルの外層を決定するために使用され、forceRender = trueの場合、destroyOnClose = falseは次のようになります。
{visible ? : <Modal visible={visible} forceRender destroyOnClose={false}><Form form={form} onFinish={handleFinish}>...</Form></Modal> : null}
問題があります:マスクのみが表示され、箇条書きは表示されません

このようにforceRender = trueとdestroyOnClose = falseを設定し、ポップアップがonOkまたはonCancelで閉じられたときに、form.resetFields()を使用すると、エラーは報告されなくなります。
<Modal visible={visible} forceRender destroyOnClose={false} > <Form form={form} onFinish={handleFinish}>...</Form> </Modal>
しかし、三項演算子visible?を使用してModalの外層を決定し、forceRender = true、destroyOnClose = falseを次のように設定すると、次のようになります。
{visible ? <Modal visible={visible} forceRender destroyOnClose={false} > <Form form={form} onFinish={handleFinish}>...</Form> </Modal> : null }
問題があります:マスクのみが表示され、箇条書きは表示されません

公式ソリューション
image
リンク

V4バージョン(関数コンポーネントにフォームが存在する)を使用すると、この問題に2日間悩まされ、ほとんどクラッシュしました(エラーが報告されましたが、使用には影響しませんでした)。最後にhttps:// antを読みました
useEffect(()=> {
return()=> {
form.resetFields();
};
})
代わりに破棄をトリガーするのは関数コンポーネント全体です()=> {....}(この時点でフォームが破棄されるかどうかはテストされていません)
ドキュメントの説明:destroyOnClose |閉じるときにモーダルの子要素を破棄します。デフォルトはfalseです。 forceRender |モーダルの必須レンダリング、デフォルトはfalse。
解決策:モーダルのforceRender = true、destroyOnClose = false、モーダルが破棄(クローズ)された場合、エラーは報告されません。フォームは内部コードの実行時に見つかりますが、入力制御IDの繰り返し警告が報告されます(エラーよりもエレガントです)。

私もこの問題に遭遇しました、私はそれをこのように解決しました
モーダル構成forceRender |強制レンダリング
Modla形式では、name = {['modal'、 'cityCode']}
フィルタ形式のName = {['search'、 'cityCode']}またはname = 'cityCode'
このようにして、すべての警告を解決でき、一意でないID警告を持つFound2要素は報告されません⚠

[フォームの名前はフォームフィールドIDのプレフィックスとして使用されます]したがって、一意でないIDを持つ2つの要素が見つかりましたという警告はありません。

getContainer = {false}をモーダルプロパティとして+ form.resetFields()を呼び出したときにモーダルを表示すると、警告が表示されなくなります

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

このように、destroyOnCloseもtrueにすることができます

Form.useFromの代わりにuseRefを使用してFormインスタンスを取得すると、機能します

  const [visible, setVisible] = useState(false)

  let form = useRef(null)

  const closeModal = () => {
    setVisible(false)
    form.resetFields()
  }

  return (
    <Modal
      title="test"
      visible={visible}
      onCancel={closeModal}
      footer={null}
    >
      <Form
        name="test"
        layout="vertical"
        onFinish={onFinish}
        ref={instance => { form = instance }}
      >
        <Form.Item
          label="item"
          name="item"
        >
          <Input />
        </Form.Item>
        <Form.Item
          style={{
            textAlign: 'right',
          }}
        >
          <Space size="middle">
            <Button type="primary" htmlType="submit">
             submit
            </Button>
            <Button onClick={closeModal}>
             cancle
            </Button>
          </Space>
        </Form.Item>
      </Form>
    </Modal>
)

ちょうど私の2セント:マウントされていないフォームをリセットしようとしたときにこのエラーが表示されたので、必要な定数に依存関係を追加すると解決しました。

useEffect(() => {
  if (data) { // data is used to populate initialValues
    form.resetFields();
  }
}, [form, data])

編集: @fabripecoが言ったことの

私はポップオーバーでフォームを使用しています、 useRefは私にとって使用可能です、私はそれがモーダルのために使用可能だと思います

const formRef = useRef(null);

<Popover
  content={renderEdit()}
  visible={isEdit}
  onVisibleChange={onToggleEdit}
>
  <span onClick={onToggleEdit}>
    {name}
  </span>
</Popover>

function renderEdit() {
  return (
    <Form
      initialValues={{ newName: name }}
      form={form}
      ref={formRef}
    >
    </Form>
  );
}

function onToggleEdit() {
  if (isEdit) {
    toggleEdit(false);
  } else if (!isEdit) {
    if (formRef.current) {
      form.setFieldsValue({
        newName: name
      });
    }
    toggleEdit(true);
  }
}

私の回避策は、 FormがレンダリングされたときにuseState ref作成し、フォームインスタンスを使用する前にref確認します。

interface FormModalProps {
  data?: RoleProps;
  visible: boolean;
  onCancel?: () => void;
  onSubmit?: (values: Store) => void;
  submitting: boolean;
}

const FormModal: React.FC<FormModalProps> = props => {
  const [form] = Form.useForm();
  const [formRef, setFormRef] = useState();  // <---- set the ref when Form Rendered

  const { data, onSubmit, onCancel, visible, submitting } = props;

  // reset Form when modal close
  useEffect(() => {
    if ( !props.visible && formRef) {  // <---- check ref before use the form instance
      form.resetFields();
    }
  }, [props.visible]);

  // fill Form when modal open
  useEffect(() => {
    if (visible && formRef) {   // <---- check ref before use the form instance
      form.setFieldsValue({
        ...data,
      });
    }
  }, [props.data]);

  // handle form onFinish
  const handleFormFinish = (values: Store) => {
    if (onSubmit) {
      onSubmit(values);
    }
  };

  // handle modal  ok
  const handleOk = () => {
    if (!form) return;
    form.submit();
  };

  return (
    <Modal
      title="Modal"
      confirmLoading={submitting}
      onOk={handleOk}
      onCancel={onCancel}
      visible={visible}
      width={640}
    >
      <Form ref={setFormRef} form={form} onFinish={handleFormFinish}>
        <Form.Item name="title" label="Title" >
          <Input />
        </Form.Item>
      </Form>
    </Modal>
  );
};

もう警告はありません!

完全に解決しました!

この警告の2つの理由:
1.1。+
2. "form.setFields()"またはuseEffect()の他の関数

私はこれを使用して解決します:

<Modal
        getContainer={false}
        // destroyOnClose
>

公式ソリューション
image
リンク

パーフェクト、モーダルにforceRenderを追加

formHookedを公​​開して、ユーザーに自分で判断させてみませんか。上記の方法に飽きませんか?

このページは役に立ちましたか?
0 / 5 - 0 評価