React Modal всегда использует одну и ту же запись из строки - PullRequest
0 голосов
/ 27 апреля 2020

, поэтому у меня есть таблица, отображающая несколько заданий из вызова API. В каждой строке таблицы есть кнопка, которая открывает модальное окно bootstrap, отображающее дополнительную информацию о задании.

Моя проблема в том, что модал, кажется, не открывается для нажатой строки. Всегда открывается указанная строка c (та, у которой самый низкий идентификатор). Кто-нибудь знает, что я делаю не так? ModalComponent

render() {
  console.log("job: ", this.props.id)
  return (
    <div className="container">
      <ReactBootstrap.Modal
        {...this.props}
        size="lg"
        aria-labelledby="contained-modal-title-vcenter"
        centered
      >
        <ReactBootstrap.Modal.Header closeButton>
          <ReactBootstrap.Modal.Title id="contained-modal-title-vcenter">
            {this.props.title}
            {this.props.employer}
          </ReactBootstrap.Modal.Title>
        </ReactBootstrap.Modal.Header>
        <ReactBootstrap.Modal.Body>
          <h4>Would you like to apply to this job?</h4>
          <p>{this.props.description}</p>
        </ReactBootstrap.Modal.Body>
        <ReactBootstrap.Modal.Footer>
          <button className="btn btn-primary" onClick={this.applyJob}>Apply</button>
          <button className="btn btn-warning" onClick={this.props.onHide}>Close</button>
        </ReactBootstrap.Modal.Footer>
      </ReactBootstrap.Modal>
    </div>
  )
}

console.log выплевывает идентификатор каждой строки в таблице.

My TableComponent передает сведения о работе каждого задания в ModalComponent следующим образом: TableComponent

<tbody>
  {
    this.props.response.map(    //  map allows you to loop around items
      job =>  //  a key is used to identify a row
        <tr key={job.id}>
          <td>{job.employer}</td>
          <td>{job.jobTitle}</td>
          <td>{job.county}</td>
          {/* <td>{job.applied + ''}</td> */}
          <td>
            {this.checkApplied(job.applied)}
          </td>
          <td><button className="btn btn-info" onClick={() => this.setState({ addModalShow: true })}>Info</button></td>
          <ApplyComponent
            show={this.state.addModalShow}
            onHide={addModalClose}
            id={job.id}
            title={job.jobTitle}
            employer={job.employer}
            county={job.county}
            description={job.description}
            status={job.applied}
          />
        </tr>
    )
  }
</tbody>

Вот изображения таблицы и модальности: enter image description here

enter image description here

Как видите, детали из нижнего ряда отображаются в модальном режиме, даже когда я нажимаю на верхнюю грести.

1 Ответ

1 голос
/ 27 апреля 2020

Проблема

Вы отображаете несколько элементов, каждый из которых может иметь свой модальный режим. Каждый из этих модалей определяет, является ли он открытым или закрытым с помощью show prop.

show prop установлен на this.state.addModalShow для каждого сопоставленного элемента.

Результат

Каждый модал будет открываться и закрываться одновременно, поскольку они основаны на одном и том же значении состояния. Щелчок по любому элементу приведет к открытию или закрытию всех.

Видимым результатом является то, что вы всегда будете видеть последний модал как открытый модал, так как он был последним для рендеринга и будет сверху.

Решение

Вот одно решение, которое потребует минимальных изменений:

Используйте разные значения в состоянии для каждого элемента.

this.props.response.map(
  job =>
    <tr key={job.id}>
      <td>{job.employer}</td>
      <td>{job.jobTitle}</td>
      <td>{job.county}</td>
      <td>
        {this.checkApplied(job.applied)}
      </td>
      <td>
      <button 
        className="btn btn-info" 
        onClick={() => {
          // Use a computed property name to make it unique based on the ID
          this.setState({ ['show_'+job.id]: true })
        }
      >Info</button></td>
      <ApplyComponent
        show={this.state['show_'+job.id]} // Use the same state value as the prop
        onHide={() => {
          // Follow the same process for closing
          this.setState({ ['show_'+job.id]: false})
        }}
        id={job.id}
        title={job.jobTitle}
        employer={job.employer}
        county={job.county}
        description={job.description}
        status={job.applied}
      />
    </tr>
)
...