#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.Хансен точно, но, как упоминал Пьер, использовать индекс карты не так разумно, но причина, по которой я сказал вам использовать его, заключается в том, что я не видел ваш код, и я не знаю никаких других уникальных данных для использования в качестве ключа.