从 dom 中删除模态,中断动画

问题描述 投票:0回答:0

我有一个使用 Nextjs、Typescript 和 tailwind 的项目。在这个项目中,我有一个模态组件。它有一些动画但是当我关闭模式时它不会从 dom 中删除并且当我有条件地渲染它时动画被破坏了。我做了一些研究并调整了我的代码并添加了 useDelayUnmount 但我的问题没有解决。

这是我的模态组件

import React, {PropsWithChildren, useEffect, useState} from 'react';
import dynamic from 'next/dynamic';
import classes from './Modal.module.scss';
import ReactDOM from 'react-dom';

interface IModal {
    onClose: (e: React.MouseEvent<HTMLSpanElement>) => void;
    nodeId?: string;
    isOpen: boolean;
    className?: string;
}

function useDelayUnmount(isMounted: boolean, delayTime: number) {
    const [showDiv, setShowDiv] = useState(false);
    useEffect(() => {
        let timeoutId: NodeJS.Timeout;
        if (isMounted && !showDiv) {
            setShowDiv(true);
        } else if (!isMounted && showDiv) {
            timeoutId = setTimeout(() => setShowDiv(false), delayTime); //delay our unmount
        }
        return () => clearTimeout(timeoutId); // cleanup mechanism for effects , the use of setTimeout generate a sideEffect
    }, [isMounted, delayTime, showDiv]);
    return showDiv;
}

const Modal: React.FC<PropsWithChildren & IModal> = ({
                                                         children,
                                                         isOpen,
                                                         nodeId,
                                                         onClose,
                                                         className,
                                                     }) => {
    const showDiv = useDelayUnmount(isOpen, 150);
    return ReactDOM.createPortal(
        showDiv &&
        <>
            {isOpen && <span onClick={onClose} className={classes.overlay}/>}
            <div
                className={`${classes.modal} ${
                    isOpen ? classes.active : ''
                } ${className}`}
            >
                <div>
                    <span
                        onClick={onClose}
                        iconName='icon-close text-2xl cursor-pointer'
                    />
                </div>
                {children}
            </div>
        </>,
        nodeId ? document.getElementById(nodeId)! : document.body
    );
};

export default dynamic(() => Promise.resolve(Modal), {
    ssr: false,
});

这是我的模态 scss 文件

.overlay {
    @apply fixed top-0 left-0 bottom-0 right-0 w-full h-full bg-black opacity-30 backdrop-blur-sm;
}

.modal {
    @apply fixed w-[600px] min-h-[250px] p-4 top-1/2 left-1/2 -translate-x-2/4 bg-white rounded-xl
  opacity-0 invisible transition-all;
}

.active {
    @apply opacity-100 visible -translate-y-2/4;
}

这是我的主页

import Head from 'next/head';
import React, {useState} from 'react';
import Button from '../components/Button/Button';
import Modal from "../components/Modal/Modal";

export default function Home() {
    const [isOpen, setIsOpen] = 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'
                />
            </Head>
            <main className='mt-6 flex flex-col gap-5'>
                <div className='flex justify-center items-center gap-5'>
                    <Modal onClose={() => setIsOpen(false)} isOpen={isOpen}>
                        Bekhab Donya
                    </Modal>
                    <Button label='Click' onClick={() => setIsOpen(true)}/>
                </div>
            </main>
        </>
    );
}

最后,我想在关闭时删除模态,我的动画也能正常工作。

提前tnx任何努力。

javascript reactjs typescript next.js tailwind-css
© www.soinside.com 2019 - 2024. All rights reserved.