.map() сопоставляет неправильное значение с моими тегами заголовка

#javascript #reactjs #reactstrap

#javascript #reactjs #reactstrap

Вопрос:

Я создаю приложение, которое позволяет сотрудникам бронировать оборудование в нашем магазине. Когда мы нажимаем кнопку «Забронировать», я использую reactstrap для открытия модального, чтобы сотрудник мог добавить дополнительную информацию. Когда открывается модальный, я хочу, чтобы название элементов было в модальном заголовке, но по какой-то причине, когда я использую .map() , оно дает всем модальным элементам одинаковый заголовок, но .map() работает для всего остального?

Чтобы сэкономить ваше время, ошибка возникает только в этом разделе кода:

 <ModalHeader toggle={this.toggle}>
  {item.name}
</ModalHeader>
  

Я не уверен, в чем проблема, и хотел бы получить любую помощь, которую я могу получить!

 {events.map(item => {
  if (item.isBooked === true) {
    return (
      <div className="col-md-4 item p-2">
        <img className="item-img-booked" src={item.img} alt="" />
        <br />
        <br />
        <h6 className="text-center">{item.name}</h6>
        <button className="btn btn-success btn-sm m-1">Return</button>
      </div>
    );
  } else
    return (
      <div className="col-md-4 item p-2">
        <img className="item-img" src={item.img} alt="" />
        <br />
        <br />
        <h6 className="text-center">{item.name}</h6>
        <Button color="danger" onClick={this.toggle}>
          Book Out
        </Button>
        <div>
          <Modal isOpen={this.state.modal} toggle={this.toggle}>
            <ModalHeader toggle={this.toggle}>
              {item.name}
            </ModalHeader>
            <ModalBody>
              Lorem ipsum dolor sit amet, consectetur adipisicing
              elit, sed do eiusmod tempor incididunt ut labore et
              dolore magna aliqua. Ut enim ad minim veniam, quis
              nostrud exercitation ullamco laboris nisi ut aliquip ex
              ea commodo consequat. Duis aute irure dolor in
              reprehenderit in voluptate velit esse cillum dolore eu
              fugiat nulla pariatur. Excepteur sint occaecat cupidatat
              non proident, sunt in culpa qui officia deserunt mollit
              anim id est laborum.
            </ModalBody>
            <ModalFooter>
              <Button color="primary" onClick={this.toggle}>
                Confrim
              </Button>
              {" "}
              <Button color="secondary" onClick={this.toggle}>
                Cancel
              </Button>
            </ModalFooter>
          </Modal>
        </div>
      </div>
    );
  }
)}
  

Комментарии:

1. .map() использует данные из массива, если заголовок неправильный, то, возможно, имя заголовка в массиве неверно.

2. @JuniusL. К сожалению, это не так. Имя в массиве указано правильно. Вы можете видеть, что я использую {item.name } в двух случаях в одном и том же отображении. Один раз это работает должным образом, а другой использует имя последнего элемента в массиве

3. пожалуйста, создайте простой рабочий проект с вашей проблемой здесь stackblitz.com

4. @JuniusL. Вот ссылка: react-us21xi.stackblitz.io/events Однако я не смог заставить reactstrap работать…

5. Я хочу увидеть код, где этот код?

Ответ №1:

Вместо того чтобы создавать модальность для каждого элемента, переместите модальность за пределы .map() и сохраните ваши элементы в состоянии. Передайте индекс каждого элемента в toggle функцию и используйте этот индекс, чтобы получить имя элемента из событий в состоянии like this.state.events[index] . Ваш модал извлекет имя из состояния.

 import React, { Component } from "react";
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";

export class EventsAll extends Component {
  state = {
    modal: false,
    index: -1,
    events: [],
    name: ""
  };

  toggle = index => {
    const ind = typeof index !== "number" ? -1 : index;

    this.setState(
      prevState => ({
        modal: !prevState.modal,
        index: ind
      }),
      () => {
        this.populateModalData();
      }
    );
  };

  populateModalData = () => {
    if (this.state.index < 0 || typeof this.state.index !== "number") {
      return;
    }

    const item = this.state.events[this.state.index];

    this.setState({
      name: item.name
    });
  };

  componentDidMount = () => {
    const { events } = this.props.events;

    this.setState({
      events: events
    });
  };

  render() {
    return (
      <div>
        <div className="row">
          {this.state.events.map((item, index) => {
            if (item.isBooked === true) {
              return (
                <div className="col-md-4 item p-2">
                  <img className="item-img-booked" src={item.img} alt="" />
                  <br />
                  <br />
                  <h6 className="text-center">{item.name}</h6>
                  <button className="btn btn-success btn-sm m-1">Return</button>
                </div>
              );
            } else
              return (
                <div className="col-md-4 item p-2">
                  <img className="item-img" src={item.img} alt="" />
                  <br />
                  <br />
                  <h6 className="text-center">{item.name}</h6>
                  <Button
                    val={index}
                    color="danger"
                    onClick={() => this.toggle(index)}
                  >
                    Book Out
                  </Button>
                  <div />
                </div>
              );
          })}
        </div>

        <Modal isOpen={this.state.modal} toggle={this.toggle}>
          <ModalHeader toggle={this.toggle}>{this.state.name}</ModalHeader>
          <ModalBody>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
            eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
            ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
            aliquip ex ea commodo consequat. Duis aute irure dolor in
            reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
            pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
            culpa qui officia deserunt mollit anim id est laborum.
          </ModalBody>
          <ModalFooter>
            <Button color="primary" onClick={this.toggle}>
              Confrim
            </Button>{" "}
            <Button color="secondary" onClick={this.toggle}>
              Cancel
            </Button>
          </ModalFooter>
        </Modal>
      </div>
    );
  }
}

export default EventsAll;
  

рабочая демо-версия

Комментарии:

1. Идеально! Спасибо за вашу помощь 🙂

Ответ №2:

Я предполагаю, что ваша функция переключения объединяет все модальности вместе, поэтому, где бы вы ни щелкнули, вам виден только последний модальный.

Попробуйте использовать массив для переключения состояния модальной видимости.

Комментарии:

1. Вы на 100% правы. Когда я удалил cdn reactstrap и нажал кнопку, он отобразил все модальности. Но как бы я использовал массив для решения этой проблемы? Извините, если я кажусь новичком, я все еще очень молодой разработчик.

Ответ №3:

Я не полностью прочитал ваш вопрос, но из названия я предполагаю, что ваша проблема в том, что вы не используете key атрибут для своих компонентов, и когда item.isBooked изменения, ваши компоненты также не меняются.

Итак, попробуйте это: измените events.map(item => { на events.map((item, index) => { , чтобы генерировать уникальный ключ каждый раз, когда map отображает элемент из events . И для ваших div внутренних функций возврата сделайте это: <div className="col-md-4 item p-2" key={index}>
<div className="col-md-4 item p-2" key={index}>

Комментарии:

1. Итак, проблема в том, что функция переключения открывает модальное значение для каждого объекта в моем массиве. Таким образом, на самом деле это правильное отображение, но поскольку оно создает модальное значение для каждого элемента, я могу видеть модальное значение только для последнего элемента в массиве, потому что оно охватывает остальные. Теперь я пытаюсь найти способ, чтобы моя функция переключения открывала только один модальный.

2. ‘keys’ — это способ, с помощью которого React знает, когда повторно отображать элемент. Передача индекса почти всегда неверна. например: вы передаете массив: он отображается, затем вы сортируете массив, индекс элемента не изменится (первый элемент всегда будет равен 0) и поэтому не повторяется.

3. @J.Хансен точно, но, как упоминал Пьер, использовать индекс карты не так разумно, но причина, по которой я сказал вам использовать его, заключается в том, что я не видел ваш код, и я не знаю никаких других уникальных данных для использования в качестве ключа.