最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Render Multiple Modals correctly with map in react-bootstrap - Stack Overflow

programmeradmin0浏览0评论

I am trying to render multiple react-bootsrap modals with map but I am unable to do so. With my current code clicking the 'View Details' button is activating all the modals at the same time instead of opening the relevant modal. Here's a snippet from 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>
      )
    })

I am trying to render multiple react-bootsrap modals with map but I am unable to do so. With my current code clicking the 'View Details' button is activating all the modals at the same time instead of opening the relevant modal. Here's a snippet from 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>
      )
    })
Share Improve this question edited Aug 6, 2017 at 21:40 Ghulam Ahmed asked Aug 6, 2017 at 21:35 Ghulam AhmedGhulam Ahmed 1291 silver badge7 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

Try making the following modifications...

Add the following change to this.state in your 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/Change the following Event Handlers. The clickHandler accepts the click event as well as an index that will be used to set the aforementioned activeModal piece of state. When react sees that the state changed it will call the render method with the new state. This is the Reactive nature of React.

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

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

Do something like this in your map function. Notice the onClick handler. Use an arrow function to catch the click event and call your clickHandler, this is so you can also pass additional arguments (this index in this case). Once the activeModal piece of state is called the ponent will be rerendered, upon doing to the show prop will evaluate to true for the appropriate clicked ponent.

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}
    />
} )
发布评论

评论列表(0)

  1. 暂无评论