Closing a related modal when the user clicks the browser's back button
Asked Answered
S

0

0

I have a simple project in which I've included a modal component that can be closed by the browser's back button. When a modal is opened, a hash appears in the URL. If the user clicks the back button, the modal is closed and the hash disappears. However, when I try to open a modal within another modal, a serious problem arises. Pressing the back button closes both modals, as the popstate callback function runs for both. I'm really stuck on this issue.

this is my index file

import Head from 'next/head'
import Image from 'next/image'
import {Inter} from 'next/font/google'
import styles from '@/styles/Home.module.css'
import {useState} from "react";
import Modal from "@/components/Modal";

const inter = Inter({subsets: ['latin']})

export default function Home() {
    const [showModal1, setShowModal1] = useState(false);
    const [showModal2, setShowModal2] = useState(false);

    return (
        <>
            <Head>
                <title>Create Next App</title>
                <meta name="description" content="Generated by create next app"/>
                <meta name="viewport" content="width=device-width, initial-scale=1"/>
                <link rel="icon" href="/favicon.ico"/>
            </Head>
            <main className={styles.main}>
                <button onClick={() => setShowModal1(true)}>Click to open modal1</button>
                <Modal hash={'#modal1'} isOpen={showModal1} onClose={() => setShowModal1(false)}>
                    This Content is used for Modal1
                    <button onClick={() => setShowModal2(true)}>
                        Click to open modal2
                    </button>
                </Modal>
                <Modal hash={'#modal2'} isOpen={showModal2} onClose={() => setShowModal2(false)}>
                    This Content is used for Modal2
                </Modal>
            </main>
        </>
    )
}

and this is my modal component

import React, {useEffect} from 'react';
import {useRouter} from "next/router";

const Modal = ({isOpen, children, onClose, hash}) => {
    const router = useRouter();
    useEffect(() => {
        if (isOpen) {
router.push(hash);
            window.addEventListener('popstate', onClose);
            return () => {
                window.removeEventListener('popstate', onClose);
            }
        }
    }, [isOpen]);

    return (
        isOpen && <div style={{
            background: 'white',
            position: 'fixed',
            top: '0',
            left: '0',
            width: '100vw',
            height: '100vh',
            display: 'flex',
            flexDirection: 'column',
            gap: '10px',
            padding: '20px'
        }}>
                <span
                    onClick={() => {
                        onClose();
                        if (router.asPath.includes(hash)) {
                            router.back();
                        }
                    }}
                    style={{
                        background: 'coral',
                        borderRadius: '10px',
                        alignSelf: 'center'
                    }}>Close Modal</span>
            {children}
        </div>
    );
};

export default Modal;

thank you in advanced for any affort

Stative answered 9/4, 2023 at 13:28 Comment(5)
Changes to hashes can be captured with the 'hashchange' event. Give it a try.Nasopharynx
didn't work. do you have any other solutionsStative
i dont fully remeber but it had something to do with closeOnNavigation: false that all dialogs closed at navigationTelluride
@Telluride I think it is for angularStative
@AliEhyaie closeOnNavigation is from angular: material.angular.io/components/dialog/apiTelluride

© 2022 - 2024 — McMap. All rights reserved.