Renz
Renz

Reputation: 91

React Antd showing multiple modal on array.map

When clicking the update button the modal pops twice, the first one shows the correct item.id but the second one is the last value on the list. any help is appreciated. tried adding {this.props.child} inside the modal tag but it doesn't work.

any help would be appreciated.

 this.state = {
  ModalText: 'Content of the modal',
  visible: false,
  currentId : 0,
  confirmLoading: false,
 }
}

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



handleOk = () => {
    this.setState({
      ModalText: 'The modal will be closed after two seconds',
      confirmLoading: true,
    });
    setTimeout(() => {
      this.setState({
        visible: false,
        confirmLoading: false,
      });
    }, 2000);
  }

  handleCancel = () => {
    console.log('Clicked cancel button');
    this.setState({
      visible: false,
    });
  }

  render(){
    const { visible, confirmLoading, ModalText } = this.state;
    return(
      <div>
        <ul>
          {this.props.user.map(item => (
            <li key={item.id}>
              The person is {item.name} and the his/her email is 
 {item.email}.

            <Button type="primary" onClick={this.showModal}>
              Update
            </Button>
            <Modal title="Title"
              visible={visible}
              onOk={this.handleOk}
              confirmLoading={confirmLoading}
              onCancel={this.handleCancel}

            >
              {item.id}
              <UpdateModal/>

            </Modal>

            </li>
          ))}
        </ul>
        </div>
    )
  }
 }

Upvotes: 2

Views: 5692

Answers (2)

Hemadri Dasari
Hemadri Dasari

Reputation: 33974

The reason the modal appears many times because

  1. This.showModal of button gets called automatically when Component renders even if you don’t click so you need to restrict that

  2. You are always showing modal without any conditional check in loop so you need conditional check for Modal

So Change

     <Button type="primary" onClick={this.showModal}>
          Update
        </Button>
        <Modal title="Title"
          visible={visible}
          onOk={this.handleOk}
          confirmLoading={confirmLoading}
          onCancel={this.handleCancel}

        >
          {item.id}
          <UpdateModal/>

        </Modal>

To

     <Button type="primary" onClick={() => this.showModal()}> //made changes here
          Update
        </Button>
      //added change here —>  {visible && <Modal title="Title"
          visible={visible}
          onOk={this.handleOk}
          confirmLoading={confirmLoading}
          onCancel={this.handleCancel}

        >
          {item.id}
          <UpdateModal/>}

        </Modal>

Upvotes: 0

Ryan Cogswell
Ryan Cogswell

Reputation: 80966

I think if you were to look at the DOM via developer tools, you would find that the modal didn't pop up twice, but rather once per item and that the one showing the last item is just the one on top. All of your modals (you are rendering one per item) are being controlled by the same visible boolean in your state, so setting that to true by clicking any of the buttons in the list will show all of the modals.

There are a few different ways you could fix this. One option is to have a single modal outside of the lis and set the item id into state when a particular button is clicked and use that state in the modal.

Upvotes: 3

Related Questions