Render Multiple Modals correct with map in react-bootstrap

I'm trying to display multiple react-bootsrap mods using a map, but I can't seem to do it. When my current code by clicking the View Details button will activate all modals at the same time instead of opening the corresponding modal. Here is a snippet of my code related to the modal:

  render() {
    const { accounts } = this.props;
    const displayAccounts = Object.keys(accounts).filter(key => {
      return accounts[key].info.type === 'student'
    }).map(key => {
      return (
        <tr key={key}>
          <th>{accounts[key].info.name}</th>
          <td>{accounts[key].info.email}</td>
          <td><Button bsStyle='danger' onClick={() => this.props.removeAccount(key)}>Remove Account</Button></td>
          <td>
            <ButtonToolbar>
              <Button id={key} bsStyle="primary" onClick={this.showModal}>View Details</Button>
              <Modal
                id={key}
                show={this.state.show}
                onHide={this.hideModal}
              >
                <Modal.Header closeButton>
                  <Modal.Title>Student Details</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                  <Table responsive striped hover>
                    <thead>
                      <tr>
                        <th>Title</th>
                        <th>Details</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr>
                        <th>Name</th>
                        <td>{accounts[key].userDetails.name}</td>
                      </tr>
                      <tr>
                        <th>Education</th>
                        <td>{accounts[key].userDetails.education}</td>
                      </tr>
                      <tr>
                        <th>GPA</th>
                        <td>{accounts[key].userDetails.gpa}</td>
                      </tr>
                      <tr>
                        <th>Skills</th>
                        <td>{accounts[key].userDetails.skills}</td>
                      </tr>
                      <tr>
                        <th>Overview</th>
                        <td>{accounts[key].userDetails.skills}</td>
                      </tr>
                    </tbody>
                  </Table>
                </Modal.Body>
                <Modal.Footer>
                  <Button onClick={this.hideModal}>Close</Button>
                </Modal.Footer>
              </Modal>
            </ButtonToolbar>
          </td>
        </tr>
      )
    })

      

+3


source to share


1 answer


Try the following changes ...

Add the following change to this.state

in constructor

to cache the active Modal index to be assigned later.

this.state = {
    ...,
    activeModal: null,
    ...,
}
this.clickHandler = this.clickHandler.bind(this);
this.hideModal = this.hideModal.bind(this);

      

Add / modify the following event handlers. clickHandler

accepts a click event as well as an index that will be used to set the above state activeModal

. When the reaction sees that the state has changed, it will call the method render

with the new state. This is the reactive nature of the reactions.



clickHandler(e, index) {
    this.setState({ activeModal: index })
}

hideModal() {
    this.setState({ activeModal: null })
}

      

Do something like this in your function map

. Pay attention to the handler onClick

. Use the arrow function to catch the click event and call it clickHandler

, so you can pass additional arguments as well (in this case index

). As soon as part of the state activeModal

is called, the component will be reloaded, after executing the show

prop command, it will evaluate to true for the corresponding component clicked

.

buttonArray.map((button, index) => {
    <Button id={key} bsStyle="primary" onClick={e => this.clickHandler(e, index)}>View Details</Button>
    <Modal
        id={key}
        show={this.state.activeModal === index}
        onHide={this.hideModal}
    />
} )

      

+1


source







All Articles