Search code examples
reactjsnext.jsreact-modal

How do I close my Modal using the react-modal component?


hi friends i'm having a problem if someone can help me i'll be very grateful, i can't find out why my modal doesn't close using shouldCloseOnOverlayClick = {true} and even without using it it doesn't close either I'll put the code: components/_App/ModalLogin.js

import React from 'react';
import ReactDOM from 'react-dom';
import Modal from 'react-modal';
import catchErrors from '../../utils/catchErrors';

const INITIAL_USER = {
    email: '',
    password: ''
}

const ModalLogin = ({isOpen, close }) => {
    const [user, setUser] = React.useState(INITIAL_USER);
    const [disabled, setDisabled] = React.useState(true);
    const [loading, setLoading] = React.useState(false);
    const [error, setError] = React.useState('');
    

    React.useEffect((modal) => {
        const isUser = Object.values(user).every(el => Boolean(el));
        isUser ? setDisabled(false) : setDisabled(true)
    }, [user]);

    const handleChange = (e) => {
        const { name, value } = e.target;
        setUser(prevState => ({ ...prevState, [name]: value }));
    }

    const handleSubmit = async e => {
        e.preventDefault();
        try {
            setLoading(true);
            setError('');
            const url = `${baseUrl}/api/login`;
            const payload = { ...user };
            const response = await axios.post(url, payload);
            handleLogin(response.data);
        } catch (error) {
            catchErrors(error, setError);
        } finally {
            setLoading(false);
        }
    }

    const customStyles = {
        content: {
            top: '50%',
            left: '50%',
            right: 'auto',
            bottom: 'auto',
            marginRight: '-50%',
            transform: 'translate(-50%, -50%)'
        }
    };
 console.log(close)

    return (
        <Modal
            isOpen={isOpen}
            style={customStyles}
            onRequestClose={close}
            shouldCloseOnOverlayClick={true}
        >

            <div className="">
                <div className="theme_login_box radius">
                    <header>
                        <h1>Fazer Login:</h1>
                        <p>Informe seu nome e e-mail para fazer login e acessar seus pedidos.</p>
                    </header>
                    <form method="POST" onSubmit={handleSubmit}>
                        <input className="radius" type="email" name="email" value={user.email} onChange={handleChange} placeholder="E-mail:" />
                        <input className="radius" type="password" name="password" value={user.password} onChange={handleChange} placeholder="Senha:" />
                        <button className="btn transition radius icon-success" type="submit" href="/" title="Minha conta" >Fazer Login</button>
                    </form>
                    <a href="#" title="Recuperar senha" className="theme_login_box_recover transition icon-alert">Esqueci minha senha</a>
                </div>
            </div>
        </Modal>
    )
};

export default ModalLogin;

my file where I invoke the modal: components/_App/StaticHeader.js

import React from 'react';
import Link from "next/link";
import Router, { useRouter } from 'next/router';
import NProgress from 'nprogress';
import { handleLogout } from '../../utils/auth';
import ModalLogin from './ModalLogin';
import ReactDOM from 'react-dom';
import Modal from 'react-modal';

Router.onRouteChangeStart = () => NProgress.start();
Router.onRouteChangeComplete = () => NProgress.done();
Router.onRouteChangeError = () => NProgress.done();



const StaticHeader = ({ user }) => {


    const router = useRouter();
    const [menuActive, setMenuActive] = React.useState(false);
    const [search, setSearch] = React.useState({ search: '' });

    //console.log(user)
    const isRoot = user && user.role == 'root';
    const isAdmin = user && user.role == 'admin';
    const isRootOrAdmin = isRoot || isAdmin;
    const [modalIsOpen, setIsOpen] = React.useState(false);

    function openModal() {
        setIsOpen(true);
    }

    function closeModal() {
        setIsOpen(false);
    }

    const isActive = (route) => {
        return route == router.pathname;
    }

    const handleOnChange = (e) => {
        const { name, value } = e.target;
        setSearch(prevState => ({ ...prevState, [name]: value }))
    }

    const handleSearch = (e) => {
        Router.push({
            pathname: '/products',
            query: { term: search.search }
        })
    }

    const menuToggle = () => {
        setMenuActive(!menuActive)
    }


    return (
        <header className="main_header">
            <div className="container">
                <div className="main_header_nav">
                    <div className="main_header_nav_logo">
                        <a href="" title="WdpShoes | Home">
                            <img alt="logo" title="logo menu" src="/css/themes/logo/wdpshoes_logo_white.png" />
                        </a>
                    </div>
                    <div className="main_header_nav_search">
                        <form action="" method="post" className="radius">
                            <input type="text" name="s" placeholder="Pesquisar na loja:" />
                            <button className="icon-search icon-notext transition"></button>
                        </form>
                    </div>
                    <div className="main_header_nav_menu">
                        <a className="icon-cart icon-notext transition main_header_nav_menu_cart" href="/cart"><span>3</span></a>
                        <div className="main_header_nav_menu_user">
                            <a href="#" title="#" className="icon-user main_header_nav_menu_user_a radius transition" onClick={openModal} >
                                {modalIsOpen && <ModalLogin isOpen={openModal} close={closeModal}/> }

                            Login</a>
                            <nav className="radius">
                                <a href="#">Meus Pedidos</a>
                                <a href="#">Meus Pedeidos</a>
                                <a href="#">Meus endereços</a>
                                <a href="#">Sair</a>
                            </nav>
                        </div>
                    </div>
                </div>

                <ul className="main_header_departments">
                    <li className="main_header_departments_li">
                        Departamento
                    <ul className="main_header_departments_li_ul">
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                        </ul>
                    </li>
                    <li className="main_header_departments_li">
                        Departamento
                    <ul className="main_header_departments_li_ul">
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                        </ul>
                    </li>
                    <li className="main_header_departments_li">
                        Departamento
                    <ul className="main_header_departments_li_ul">
                            <li className="main_header_deprtaments_li_ul_li"><a href="">Categoria</a></li>
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                        </ul>
                    </li>
                    <li className="main_header_departments_li">
                        Departamento
                    <ul className="main_header_departments_li_ul">
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                            <li className="main_header_departments_li_ul_li"><a href="">Categoria</a></li>
                        </ul>
                    </li>

                </ul>
            </div>
        </header>
    );
}

export default StaticHeader;

What could I be changing to make my modal work as expected if someone can help me thanks


Solution

  • The issue is that you have encapsulated your modal inside the <a /> tag and in there you have an onClick which calls openModal. Once you click on "close" inside your modal the event propagates and triggers the click on <a /> tag.

    To fix the issue just pull put the <Modal /> outside of your <a /> tag.

    <a href="#" title="#" className="icon-user main_header_nav_menu_user_a radius transition" onClick={openModal} >Login</a>
    
    {modalIsOpen && <ModalLogin isOpen={modalIsOpen} close={closeModal}/> }