0

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;
Suresh Kumar
  • 119
  • 2
  • 10
  • 1
    Your code works fine. Check it [here](https://codesandbox.io/s/black-wildflower-8xcl2?file=/src/App.js). I think you have a styling issue. Make sure that your close button is clickable and nothing overlaps it. – aytek Oct 06 '21 at 13:24

3 Answers3

2

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;
Sastrabudi
  • 68
  • 1
  • 6
1

You need to start debuging it, You start to test your button if onClick works or not

  <div className="close">
   <button onClick={() => alert('button cliked')}>X</button>
  </div> 
Mr mael
  • 15
  • 1
  • 5
  • Hi, Thanks, I checked, but it seems, the button is calling the function when clicked, the closeModal fuction also works, but the setModalState is not changing the state. Still I can't find why the state is not changing. – Suresh Kumar Oct 06 '21 at 14:05
0

You have to use it like so:

   class Foo extends Component {
  handleClick = () => {
    console.log('clicked');
  }
  render() {
    return <button onClick={this.handleClick}>click here</button>;
  }
}

As stated in react documentation here :

You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.

This is not React-specific behavior; it is a part of how functions work in JavaScript. Generally, if you refer to a method without () after it, such as onClick={this.handleClick}, you should bind that method.

Sabshane
  • 184
  • 2
  • 11
  • Hi, Thanks, I am doing that. The problem I found is in setting the state through setModalState(false). I don't get it why its not changing the state. – Suresh Kumar Oct 06 '21 at 14:15