#javascript #reactjs #react-hooks
Вопрос:
Реагируй, новичок. Я видел предыдущие предложения SO, но они не помогают мне в той схеме, которой я следовал здесь. Пожалуйста, может ли кто-нибудь сказать мне, как я определяю, что нажатая кнопка запускает только соответствующий модал в этом коде? Я хотел бы получить некоторую помощь в работе над этим кодом, так как потребовалось некоторое время, чтобы собрать его воедино, и я понимаю кое-что из того, что здесь происходит. Опытные программисты увидят здесь мои детские шаги. Спасибо.
This is the returned json
{
"cakes": [
{
"id": 1,
"text": "Fruit Sponge Layer Cake",
"comment": "Real fruit - strawberries, Victoria Sponge and cream",
"image": "./assets/fruitLayerSponge.jpg",
"alt": "Fruit Sponge",
"yum": 1,
"name": "fruitSponge"
},
{
"id": 2,
"text": "Chocolate Muffin",
"comment": "Chocolate mix, chocco chips and cream",
"image": "./assets/chocoMuffinsWCream.jpg",
"alt": "Chocco Muffin",
"yum": 3,
"name": "choccoMuffin"
},
{
"id": 3,
"text": "Strawberry Cheesecake",
"comment": "Cheesecake with strawberry cream",
"image": "./assets/strawberryCheesecake.jpg",
"alt": "Cheesecake",
"yum": 2,
"name": "cheesecakeStrawberry"
}
]
}
This is the React Component - AsyncAwaitLocalhost.jsx
import React from 'react';
import "./App.css"
import { Modal, Button } from "react-bootstrap";
class AsyncAwaitLocalhost extends React.Component {
constructor(props) {
super(props);
this.state = {
jsonContent: [],
greeting: "string",
newGreeting: "Hello",
isOpen: false
};
}
async componentDidMount() {
// GET request using fetch with async/await
const response = await fetch('http://localhost:8080/cakes');
const data = await response.json();
this.setState({ jsonContent: data.cakes, greeting: this.state.greeting, newGreeting: this.state.newGreeting })
}
openModal = () => this.setState({ isOpen: true });
closeModal = () => this.setState({ isOpen: false });
render() {
const { jsonContent } = this.state;
const { greeting } = this.state;
const { newGreeting } = this.state;
this.state.greeting = "Hello greeting";
this.state.newGreeting = "Hi new greeting";
console.log("greeting: " greeting);
console.log("newGreeting: " newGreeting);
// the inline JSX render component definition
const Cake = ({ name, id, text, image, comment, dbutton, dmodal }) => (
<div>
<img src={image} width="120px" alt={name}/>
<div>
<p>{name}</p>
<p>{text}</p>
<p>{comment}</p>
<p>{id}</p>
<div>{dbutton}</div>
<p>amp;nbsp;</p>
<div id="dModal" className="dModalClosed">{dmodal}</div>
<p>amp;nbsp;</p>
</div>
</div>
);
return (
<div className="card text-center m-3">
<h5 className="card-header">See Cakes</h5>
<div className="card-body">
<div>
{this.state.jsonContent.map((cake, index) => (
<Cake
name={`${cake.id} ${cake.name}`}
image={cake.image}
text={cake.text}
comment={cake.comment}
key={index}
dbutton={<Button onClick={this.openModal}>See more {cake.id}</Button>}
dmodal={
<Modal id={cake.name} show={this.state.isOpen} onHide={this.closeModal}>
<Modal.Header closeButton>
<Modal.Title>{cake.text}</Modal.Title>
</Modal.Header>
<Modal.Body>name={`${cake.id} ${cake.name}`}
image={cake.image}
text={cake.text}
comment={cake.comment}
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.closeModal}>
Close
</Button>
</Modal.Footer>
</Modal>
}
/>
))}
<div>
</div>
</div>
</div>
</div>
);
}
}
export { AsyncAwaitLocalhost };
Комментарии:
1. В настоящее время вы используете одно и то же
isOpen
состояние для всех модалов. Вам нужно будет отслеживать состояние «открыто» для каждого отдельного модала.
Ответ №1:
Потому что вы используете логическое значение для управления open для всех модальных. Вам нужно использовать идентификатор/индекс, чтобы контролировать это:
this.state = {
isOpen: null
};
...
onClick={this.openModal(index)}
...
openModal = (index) => () => this.setState({ isOpen: index });
closeModal = () => this.setState({ isOpen: null });
...
show={this.state.isOpen === index}
Комментарии:
1. Спасибо @Viet. Реализация вашего решения заняла минуту или две, и проблема была решена немедленно.
Ответ №2:
Обе эти линии меняются isOpen
в зависимости от вашего состояния AsyncAwaitLocalhost
.
openModal = () => this.setState({ isOpen: true });
closeModal = () => this.setState({ isOpen: false });
Все ваши модалы настроены на отображение, когда this.state.isOpen
это верно:
<Modal id={cake.name} show={this.state.isOpen} onHide={this.closeModal}>
Таким образом, всякий раз , когда вы устанавливаете this.state.isOpen
значение true на своем AsyncAwaitLocalhost
, как это происходит всякий раз, когда вы звоните openModal()
, будут отображаться все модалы.
Вы должны либо разбить модалы на их собственные компоненты и сохранить это в состоянии отдельных модалов, либо где-то сохранить идентификатор, указывающий вашему коду, какой модал открывать.