I am a beginner to React, I have been designing a simple ecommerce page, and I am facing this issue. I have created two functions, openModal and closeModal, which change the state of the Modal box that I created. It closes while I used the closeModal function in Modal tag, but it does not close if it is closed by the inner button element. I could not find any answers, could anyone tell me where I made a mistake?
import './Cards.css'
import Modal from 'react-modal'
import { useState } from 'react';
import './Cards.css'
const Cards = ({ name }) => {
const [modalState, setModalState] = useState(false);
const openModal = () => {
setModalState(true)
}
const closeModal = () => {
setModalState(false)
}
return (
<div className="card" onClick={openModal}>
<div className="cardImage">
<img src={name.img} />
</div><br />
<div className="cardText">
<p>{name.brand}</p>
<p>{name.model}</p>
<p>{name.price}</p>
</div>
<Modal isOpen={modalState} onRequestClose={closeModal}>
<div className="close"><button onClick={closeModal}>X</button></div><br/>
<div>
<span className="modalimage"><img src={name.img} /></span>
<span className="modaltext">
<h2>Description</h2>
<p>uehqirfuh fwejhgwfejk wre fwigw giuewhj jfnkjw ejirf nlwekf hwjf iwue gkjenv iw niguew nviuwne iuwenv jkwnb bewiurfh hewuihneiwujk gnewui kjlsfnviwejkrgnewui niuwjg weui nuweoirjgnewujkgneuijkgn ein wiuegniwjrk</p>
<br/>
<h2>Price</h2>
<h3>Rs.{name.price}</h3>
<button className="buy">Buy Now</button>
<button className="cart">Add to Cart</button>
</span>
</div>
</Modal>
</div>
)
}
export default Cards;
Try to use anonymous function on the OnClick event, for each button. Because when you dont' use the anonymous function on the OnClick event, the "closeModal" function will be triggered on every render (Reference: React OnClick Function Fires On Render)
Your code should be like this:
import './Cards.css'
import Modal from 'react-modal'
import { useState } from 'react';
const Cards = ({ name }) => {
const [modalState, setModalState] = useState(false);
const openModal = () => {
setModalState(true)
}
const closeModal = () => {
setModalState(false)
}
return (
<div className="card" onClick={()=>openModal()}>
<div className="cardImage">
<img src={name.img} />
</div><br />
<div className="cardText">
<p>{name.brand}</p>
<p>{name.model}</p>
<p>{name.price}</p>
</div>
<Modal isOpen={modalState} onRequestClose={closeModal}>
<div className="close"><button onClick={()=>closeModal()}>X</button></div><br/>
<div>
<span className="modalimage"><img src={name.img} /></span>
<span className="modaltext">
<h2>Description</h2>
<p>uehqirfuh .........</p>
<br/>
<h2>Price</h2>
<h3>Rs.{name.price}</h3>
<button className="buy">Buy Now</button>
<button className="cart">Add to Cart</button>
</span>
</div>
</Modal>
</div>
)
}
export default Cards;
Or maybe you want to make your website prettier too, you can use modals that have been included in bootstrap. Bootstrap 5 Modal Documentation
UPDATE 07/10/2021
I tried to use e.stopPropagation();
on close modal function and now the button can close the modal. (Credits to this answer: Unable to close modal)
Your new code should be like this:
import './Cards.css'
import Modal from 'react-modal'
import { useState } from 'react';
const Cards = ({ name }) => {
const [modalState, setModalState] = useState(false);
const openModal = () => {
setModalState(true)
}
const closeModal = (e) => {
e.stopPropagation();
setModalState(false)
}
return (
<div className="card" onClick={()=>openModal()}>
<div className="cardImage">
<img src={name.img} />
</div><br />
<div className="cardText">
<p>{name.brand}</p>
<p>{name.model}</p>
<p>{name.price}</p>
</div>
<Modal isOpen={modalState} onRequestClose={(e) => closeModal(e)}>
<div className="close"><button onClick={(e) => closeModal(e)}>X</button></div><br />
<div>
<span className="modalimage"><img src={name.img} /></span>
<span className="modaltext">
<h2>Description</h2>
<p>uehqirfuh .........</p>
<br />
<h2>Price</h2>
<h3>Rs.{name.price}</h3>
<button className="buy">Buy Now</button>
<button className="cart">Add to Cart</button>
</span>
</div>
</Modal>
</div>
)
}
export default Cards;