Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modal and form validation no destory #8684

Closed
basicfu opened this issue Dec 20, 2017 · 13 comments
Closed

modal and form validation no destory #8684

basicfu opened this issue Dec 20, 2017 · 13 comments

Comments

@basicfu
Copy link

basicfu commented Dec 20, 2017

Version

3.0.0

Environment

mac

Reproduction link

https://user-images.githubusercontent.com/26153901/34207207-75573d12-e5c4-11e7-9a0e-af7932d58aec.gif

Steps to reproduce

According to the official website example add modal

address

repat

1.invoke add function
2.invoke remove function
3.invoke open function
4.input value
5.invoke modal ok function

gif

image

code

import React, { Component } from 'react';
import { Button, Form, Icon, Input, Modal } from 'antd';

@Form.create()
export default class Home extends React.Component {
  state={
    modalVisible: false,
  }
  open=() => {
    this.setState({ modalVisible: true });
  }
  cancel=() => {
    this.setState({ modalVisible: false });
  }
  ok=() => {
    this.props.form.validateFields((errors) => {
      if (errors) {
        console.log('no pass');
        return;
      }
      console.log('pass');
    });
  }
  remove = () => {
    const { form } = this.props;
    form.setFieldsValue({
      keys: [1],
    });
    console.log('remove two input');
  }
  add = () => {
    const { form } = this.props;
    form.setFieldsValue({
      keys: [1, 2, 3],
    });
    console.log('load three input');
  }

  render() {
    const { getFieldDecorator, getFieldValue } = this.props.form;
    const { modalVisible } = this.state;
    getFieldDecorator('keys', { initialValue: [] });
    const keys = getFieldValue('keys');
    const formItems = keys.map((k) => {
      return (
        <Form.Item required={false} key={k} >
          {getFieldDecorator(`names[${k}]`, {
            rules: [{
              required: true,
              message: "Please input passenger's name or delete this field.",
            }],
          })(
            <Input placeholder="passenger name" />
          )}
        </Form.Item>
      );
    });
    const modalProps = {
      visible: modalVisible,
      onOk: this.ok,
      onCancel: this.cancel,
    };
    return (
      <div>
        <Modal {...modalProps}> {
          <Form layout="horizontal">
            {formItems}
          </Form>
        }
        </Modal>
        <Button type="dashed" onClick={this.add}>
          <Icon type="plus" /> add3
        </Button>
        <Button type="dashed" onClick={this.remove}>
          <Icon type="plus" /> remove2
        </Button>
        <Button type="dashed" onClick={this.open}>
          <Icon type="plus" /> show
        </Button>
      </div>
    );
  }
}

What is expected?

invoke modal ok function after,The first input box and the second input box should be destroyed

What is actually happening?

The first input box and the second input box are not destroyed,It causes validation not to pass


How do I destroy the components that I created before?

@basicfu
Copy link
Author

basicfu commented Dec 20, 2017

if the change is not a problem for the following code, componentize the form and give the unique key,Is there a better solution?

import React, { Component } from 'react';
import { Button, Form, Icon, Input, Modal } from 'antd';

class CustomizedForm extends React.Component {
  ok=() => {
    this.props.form.validateFields((errors) => {
      if (errors) {
        console.log('no pass');
        return;
      }
      console.log('pass');
    });
  }
  render() {
    const { visible, onCancel, v } = this.props;
    const { getFieldDecorator } = this.props.form;
    const formItems = v.map((k) => {
      return (
        <Form.Item required={false} key={k} >
          {getFieldDecorator(`names[${k}]`, {
            rules: [{
              required: true,
              message: "Please input passenger's name or delete this field.",
            }],
          })(
            <Input placeholder="passenger name" />
          )}
        </Form.Item>
      );
    });
    const modalProps = {
      visible,
      onOk: this.ok,
      onCancel,
    };
    return (
      <Modal {...modalProps}> {
        <Form layout="horizontal">
          {formItems}
        </Form>
      }
      </Modal>
    );
  }
}
const Custom = Form.create({})(CustomizedForm);

let index=0;
export default class Home extends React.Component {
  state={
    modalVisible: false,
    v: [],
  }
  remove = () => {
    index++;
    this.setState({ v: [4] });
  }
  add = () => {
    index++;
    this.setState({ v: [1, 2, 3] });
  }
  cancel=() => {
    this.setState({ modalVisible: false });
  }
  open=() => {
    this.setState({ modalVisible: true });
  }
  render() {
    const { modalVisible, v } = this.state;
    return (
      <div>
        <Custom key={index} visible={modalVisible} onCancel={this.cancel} v={v} />
        <Button type="dashed" onClick={this.add}>
          <Icon type="plus" /> add3
        </Button>
        <Button type="dashed" onClick={this.remove}>
          <Icon type="plus" /> remove2
        </Button>
        <Button type="dashed" onClick={this.open}>
          <Icon type="plus" /> show
        </Button>
      </div>
    );
  }
}

@HunDunDM
Copy link

I found the problem is that the ref of Input is not called, when Modal is not visible. So automatic delete in saveRef(rc-form) does not trigger.
I think it should be helpful to find the problem.

@basicfu
Copy link
Author

basicfu commented Dec 21, 2017

Thank you,I now use the second method, in visible is true,The key to increase 1 set modal,So every time open the modal is rendering a different modal

@HunDunDM
Copy link

HunDunDM commented Dec 21, 2017

@basicfu
According to my experience, you can try const formItems = !modalVisible ? null : keys.map((k) => ...... in the first code.

@basicfu
Copy link
Author

basicfu commented Dec 21, 2017

@HunDunDM Really can use the way you said,Thank you

@benjycui
Copy link
Contributor

Please provide a re-producible demo: https://u.ant.design/codesandbox-repro

@basicfu
Copy link
Author

basicfu commented Dec 21, 2017

const formItems = !modalVisible ? null : keys.map((k) => ......

In this way can solve

@HunDunDM
Copy link

re-producible
I guess the reason

I found the problem is that the ref of Input is not called, when Modal is not visible. So automatic delete in saveRef(rc-form) does not trigger.

@benjycui
Copy link
Contributor

@afc163 how about just add a Modal[forceRender]? Just like Tabs.TabPane and Menu

@benjycui
Copy link
Contributor

Actually, I think we should add forceRender to Tooltip and so on, too.

@basicfu
Copy link
Author

basicfu commented Dec 22, 2017

Can you provide an active destroy all form method?

@benjycui
Copy link
Contributor

Can you provide an active destroy all form method?

Please provide more details and use cases.

@afc163
Copy link
Member

afc163 commented Jul 13, 2018

Try destroyOnClose

@afc163 afc163 closed this as completed Jul 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants