I want to make a modal for my App. I've tried everything, and my closeicon won't close my modal. It works fine when I do modal in the same file, but I want make my modal as separate component. Is something wrong with my code?
Parent Component:
import { Card, Placeholder, Image, Icon } from "semantic-ui-react";
import BookModal from "./BookModal";
import { useState } from "react";
const BookCard = props => {
const [showModal, setShowModal] = useState(false)
return (
<Card onClick={() => setShowModal(true)}>
<Image><Placeholder><Image src={props.image} size="large" /></Placeholder></Image>
<Card.Content>
<Card.Header>{props.title}</Card.Header>
<Card.Meta>
<span className='date'>{props.publishedDate}</span>
</Card.Meta>
<Card.Description>{props.author}</Card.Description>
</Card.Content>
<Card.Content extra>
<Icon name='star'>Rating</Icon>
</Card.Content>
<BookModal key="Modal1" open={showModal} onClose={() => setShowModal(false)}/>
</Card>
);
}
export default BookCard;
Children Component Modal:
import { Modal } from "semantic-ui-react";
const BookModal = props => {
return (
<Modal
closeIcon
onClose={props.onClose}
open={props.open} >
<Modal.Header>
<h2>Modal content</h2>
</Modal.Header>
</Modal>
);
}
export default BookModal;
You have run into an interesting problem -- when you click the X icon to close the modal, the <Card> component also receives this click!
So the onClick handler in the card code runs when you try to close the modal, and sets the open state to true again. This happens after the onClose handler in the modal is run, so the modal will stay open.
You can change the code to open modal on the <Image> click instead:
<Card>
<Image
onClick={() => setShowModal(true)}
>
<Placeholder>
<Image src={props.image} size="large" />
</Placeholder>
</Image>
<Card.Content>
<Card.Header>{props.title}</Card.Header>
<Card.Meta>
<span className="date">{props.publishedDate}</span>
</Card.Meta>
<Card.Description>{props.author}</Card.Description>
</Card.Content>
<Card.Content extra>
<Icon name="star">Rating</Icon>
</Card.Content>
<BookModal
key="Modal1"
open={showModal}
onClose={() => setShowModal(false)}
/>
</Card>
You can see it all working here: https://codesandbox.io/s/semantic-ui-example-forked-yy7p3?file=/BookCard.js
Because the <Image> component is a sibling and not the parent of the <BookModal> component, the click will not "fall through" or "bubble up" (whatever semantics you prefer) into it.
Another way is to keep the modal trigger inside the modal. This is how their own examples do it -- you can find a simplified one here: https://codesandbox.io/s/semantic-ui-example-forked-qo99z?file=/example.js