im trying to make a subpage for a record label, i need to display all the artists on cards and then have their full profile displayed on a modal, whenever i try to open the modal all of them open and close when i click the card button, i've tried creating a constructor(props) with state component but wasnt able to make the state recieve the key id of the artist . i've been trying for weeks trying to adapt other examples to my own code with no results, Thank you so much for your time!
import React, {useState, setShow, Component} from 'react';
import {CardDeck, Navbar, NavLink, Col, Row, Image, Container, Card, CardImg, CardBody, CardText } from 'react-bootstrap';
import Button from 'react-bootstrap/Button';
import Modal from 'react-bootstrap/Modal';
const Artistas = [ {id:1,
img:require("../assets/images/artists-01.jpg"),
title: 'Artist 1',
content: 'Lorem Ipsum',
musica:"https://open.spotify.com/embed/artist/1wA3nwZy9EriceVVQlEmEx",
genres:["Punk ", "Rock"]},
{id: 2,
img:require("../assets/images/artists-04.jpg"),
title: "Artist 2",
content: 'lorem ipsum',
musica:"https://open.spotify.com/embed/artist/1wA3nwZy9EriceVVQlEmEx"},
];
function ArtistsPage() {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const Artistxs = Artistas.map(artist =>
<div>
<Card key={artist.id}>
<Card.Img variant="top" src={artist.img} />
<Card.Body>
<Button onClick={handleShow}>{artist.title}</Button>
<Card.Text>
</Card.Text>
</Card.Body>
</Card>
<>
<Modal
show={show}
onHide={handleClose}
backdrop="static"
keyboard={false}
centered
size="lg"
>
<Modal.Header closeButton>
<Modal.Title>{artist.title}</Modal.Title>
</Modal.Header>
<Modal.Body className="row">
<div class="col-md-8">
<Image src={artist.img} />
</div>
<div class="col-md-4">
<p>{artist.content}</p>
</div>
</Modal.Body>
<Modal.Footer>
<Button onClick={handleClose} >
Close
</Button>
</Modal.Footer>
</Modal>
</>
</div>
)
return(
<div>
<Container className="container">
<Row className="row">
<Col className="">{Artistxs}
</Col>
</Row>
</Container>
</div>
);
}
export default ArtistsPage;
You can create separate component for Modal and pass the object through Props to display relevant info and handle modal events.
In example below, not toggling the actual modal but u can use the props to toggle it.
function ArtistAddtionalInfo(props) {
return (
// Modal can be here with details in artistInfo and other props
<div className="modal_dummy">
Below Props can be used to handle actual model popup
<h1> Hello, { props.artistInfo.title }</h1>
<div>{ props.artistInfo.id }</div>
<div>{ props.artistInfo.img }</div>
<div>{ props.artistInfo.content }</div>
<div>showModel: {props.showModel ? 'true' : 'false'}</div>
<button onClick = {() => props.handleModalClose()} > close </button>
</div>
)
}
class TodoApp extends React.Component {
constructor(props) {
super(props)
this.state = {
items: [ {id:1,
img:"../assets/images/artists-01.jpg",
title: 'Artist 1',
content: 'Lorem Ipsum',
musica:"https://open.spotify.com/embed/artist/1wA3nwZy9EriceVVQlEmEx",
genres:["Punk ", "Rock"]},
{id: 2,
img:"../assets/images/artists-04.jpg",
title: "Artist 2",
content: 'lorem ipsum',
musica:"https://open.spotify.com/embed/artist/1wA3nwZy9EriceVVQlEmEx"},
],
artistInfo: {},
isShowModel: false
}
}
handleShow = (artist) =>{
this.setState({
artistInfo:artist,
isShowModel: true
});
}
handleOnhide = () =>{
this.setState({
isShowModel: false
});
}
render() {
return (
<div className="container">
<div className="row">
<div className="">
{
this.state.items.map(artist =>
<div className="card" key={artist.id}>
<img className="card_image" src={artist.img} />
<div className="card_body">
<button onClick={ () => { this.handleShow(artist)}}> {artist.title} </button>
<div className="card_text">
</div>
</div>
</div>
)
}
</div>
</div>
{
this.state.isShowModel &&
<ArtistAddtionalInfo
artistInfo = { this.state.artistInfo }
showModel = {this.state.isShowModel}
handleModalClose = {() => {this.handleOnhide()}}
/>
}
</div>
)
}
}
ReactDOM.render(<TodoApp />, document.querySelector("#app"))
JSFiddle see it in action