I am trying to a make Gallery application using React.JS and Reactstrap. I'm using the map()
function to display every piece of art in a Card. In every card, there is a button that opens a modal to show more data from the map function. My problem is when I'm clicking the button to open modal from any card it shows the data from the last card on the page.
The code:
const Artcards = ({ state, loading }, props) => {
const { buttonLabel, className } = props;
const [modal, setModal] = useState(false);
const toggle = () => setModal(!modal);
if (loading) {
return <h2>Loading</h2>;
}
return (
<CardGroup className="CardGroup">
{state.map((state, index) => {
return (
<div key={index}>
<Card className="Card" style={{ padding: "0", height: "39rem" }}>
<CardBody className="pt-3">
<CardTitle className="CardTitle">
Art Name:
<h6 className="CardParagraph">{state.artName}</h6>
</CardTitle>
<CardSubtitle>
Artist Name:
<h6 className="CardParagraph">{state.artistName}</h6>
</CardSubtitle>
<CardImg
top
src={state.source}
alt={state.artName}
/>
</CardBody>
<CardBody>
<CardText>
Description:
<div className="CardParagraph">{state.description}</div>
</CardText>
<CardText>
Price:<div className="CardParagraph">{state.price} </div>
</CardText>
<Button size="sm" color="danger" className=" m-1">
Buy
</Button>
<br></br>
<Button color="success" onClick={toggle}>
Contact Artist
</Button>
</CardBody>
<Modal
isOpen={modal}
state={state}
fade={false}
toggle={toggle}
className={className}
>
<ModalHeader className="bg-dark text-primary" toggle={toggle}>
here the {state.artistName} should be
</ModalHeader>
<ModalBody>
<p>Header:{state.artName}</p>
<textarea
style={{ overflow: "auto", resize: "none"}}
rows="5"
cols="60"
placeholder="Write your message"
></textarea>
<Input
type="text"
placeholder="Write Email or Tel number for response"
></Input>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={toggle}>
Send message
</Button>{" "}
<Button color="secondary" onClick={toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
</Card>
</div>
);
})}
</CardGroup>
);
};
What you are doing here isn't opening only the last, but you are opening all modals and only the last is showing because is on top of all others.
What you need to do is have only one modal and save the index of the clicked card and then only display the data from that card.
So here is what you need to do
.map
You also have some kind of weird use of the variable state
in alot of places where you have state
comming from props and then using the same name inside .map
. You should change that name to something more descriptive, because this makes things very confusing.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.