私のコンポーネントの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>
...
モーダルの[保存]ボタンをクリックしてフォームを送信するにはどうすればよいですか?
私の解決策は、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>
);
}
よりクリーンに見える新しいソリューションがあります:
<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
あなたは公式の例を学ぶことができます: https://ant.design/components/form/#components-form-demo-form-in-modal
私の解決策は、モーダルのフッターを無効にし、独自の送信ボタンを作成することでした:
<Modal footer={null}>
<Form onSubmit={this.customSubmit}>
...
<FormItem>
<Button type="primary" htmlType="submit">Submit</Button>
</FormItem>
</Form>
</Modal>
このソリューションでモーダルをラップする必要はありません。
これで、反応フックがなくなりました。フックを使用しても同じことができます。モーダルのラッパーコンポーネントを作成し、フォームがある場所でそのコンポーネントを使用する。
ラッパーコンポーネント:
<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を持つラッパーモーダルコンポーネントを作成しました。また、モーダル用のカスタムボタンを作成しています
私の解決策
...
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>
...
アイデアは、ラップされたフォームコンポーネントの参照を設定することです。
以下の参考資料をご覧ください。