Suresh Kumar
Suresh Kumar

Reputation: 119

How can I make a "function inside a react-modal element work"?

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;

Upvotes: 0

Views: 1076

Answers (3)

Sastrabudi
Sastrabudi

Reputation: 68

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;

Upvotes: 2

Sabshane
Sabshane

Reputation: 241

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.

Upvotes: 0

Mr mael
Mr mael

Reputation: 15

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> 

Upvotes: 1

Related Questions