web-dev-qa-db-ja.com

Antd反応コンポーネントライブラリを使用してモーダルダイアログでフォームコンポーネントを送信する方法

私のコンポーネントのrenderメソッドには、親としてantd Modalコンポーネント、子としてantd Formコンポーネントがあります。

    render() {
        const myForm = Form.create()(AddNewItemForm);
        ...
        return (
            ...
            <Modal
                title="Create new item"
                visible={this.state.visible}
                onOk={this.handleOk}
                onCancel={this.handleCancel}
                wrapClassName="vertical-center-modal"
                okText="Save new item"
                width="600"
            >
                <myForm />
            </Modal>
...

モーダルの[保存]ボタンをクリックしてフォームを送信するにはどうすればよいですか?

11
vladimirp

私の解決策は、handleCreateメソッドで子フォームコンポーネントを検証する新しいラッパー親コンポーネントでモーダルダイアログとフォームコンポーネントをラップすることでした。 ref属性を使用して、FormOnModalWrapperコンポーネント内のmyForm子コンポーネントを参照しました。ラッパーの親コンポーネントからmyFormコンポーネントインスタンスに小道具を介して親ハンドラーを渡しています。

class FormOnModalWrapper extends React.Component {
...
    constructor(props) {
        this.state =
        {
            visible: false
            ....
        }

...
    showModal = () => {
        this.setState({
            visible: true,
        });
    }

    handleCreate = () => {
        const form = this.form;
        form.validateFields((err, values) => {
            if (err) {
                return;
            }
            console.log('Received values of form: ', values);
            form.resetFields();
            this.setState({ visible: false });
        });
    }

    saveFormRef = (form) => {
        this.form = form;
    }

render() {
...
    const myForm= Form.create()(CrateNewItemFormOnModal);
...
    return (
      <div>
            <Button onClick={this.showModal}>Add</Button>
            <myForm
                visible={this.state.visible}
                onCancel={this.handleCancel}
                onCreate={this.handleCreate}
                ref={this.saveFormRef}
            />
      </div>
     );
}

CrateNewItemFormOnModalコンポーネントクラスには、親としてモーダルダイアログコンポーネントがあり、子としてフォームコンポーネントがあります。

export default class AddNewItemForm extends React.Component {

render() {
    ...
    const { visible, onCancel, onCreate, form } = this.props;
    ...
    return (
        <Modal
           title="Create new item"
           visible={visible}
           onOk={onCreate}
           onCancel={onCancel}
           okText="Create"
        >
          <Form>
            ...
          </Form>
        </Modal>
    );
}
5
vladimirp

よりクリーンに見える新しいソリューションがあります:

<Form id="myForm">

...

<Modal
    ...
    footer={[
        <Button form="myForm" key="submit" htmlType="submit">
            Submit
        </Button>
        ]}
>
    <CustomForm />
</Modal>

これは、ボタンのform属性のために機能します。 ブラウザのサポート

元のソリューションの作者: https://github.com/ant-design/ant-design/issues/938

3
sensor

あなたは公式の例を学ぶことができます: https://ant.design/components/form/#components-form-demo-form-in-modal

2
benjycui

私の解決策は、モーダルのフッターを無効にし、独自の送信ボタンを作成することでした:

<Modal footer={null}>
  <Form onSubmit={this.customSubmit}>
    ...
    <FormItem>
      <Button type="primary" htmlType="submit">Submit</Button>
    </FormItem>
  </Form>
</Modal>

このソリューションでモーダルをラップする必要はありません。

1
JacopoStanchi

これで、反応フックがなくなりました。フックを使用しても同じことができます。モーダルのラッパーコンポーネントを作成し、フォームがある場所でそのコンポーネントを使用する。

ラッパーコンポーネント:

 <Modal
  visible={state}
  centered={true}
  onCancel={() => setState(false)}
  title={title}
  destroyOnClose={true}
  footer={footer}>
  {children}
</Modal>

フォームコンポーネント:

   <WrapperModal
    state={modalState}
    setState={setModal}
    title='Example Form'
    footer={[
      <button onClick={handleSubmit}>
        SUBMIT
      <button/>
    ]}>
    <Form>
          <Form.Item label='name '>
            {getFieldDecorator('name ', {
              rules: [
                {
                  required: true,
                  message: 'please enter proper name'
                }
              ]
            })(<Input placeholder='name'/>)}
          </Form.Item>
    </Form>
  </WrapperModal>

ここで、モーダルに必要なすべてのAPIを持つラッパーモーダルコンポーネントを作成しました。また、モーダル用のカスタムボタンを作成しています

1
Wasif

私の解決策

...
handleOk = (e) => {
   e.preventDefault();
   this.form.validateFields((err, values) => {
      //do your submit process here
   });
}
//set ref form
formRef = (form) => {
  this.form = form;
}
render() {
    const myForm = Form.create()(AddNewItemForm);
    ...
    return (
        ...
        <Modal
            title="Create new item"
            visible={this.state.visible}
            onOk={this.handleOk}
            onCancel={this.handleCancel}
            wrapClassName="vertical-center-modal"
            okText="Save new item"
            width="600"
        >
            <myForm
               ref={this.formRef}
            />
        </Modal>
...

または、このソリューションを使用できます

...
handleOk = (e) => {
   e.preventDefault();
   this.form.validateFields((err, values) => {
      //do your submit process here
   });
}
render() {
    const myForm = Form.create()(AddNewItemForm);
    ...
    return (
        ...
        <Modal
            title="Create new item"
            visible={this.state.visible}
            onOk={this.handleOk}
            onCancel={this.handleCancel}
            wrapClassName="vertical-center-modal"
            okText="Save new item"
            width="600"
        >
            <myForm
               wrappedComponentRef={(form) => this.formRef = form}
            />
        </Modal>
...

アイデアは、ラップされたフォームコンポーネントの参照を設定することです。

以下の参考資料をご覧ください。

参考