search

Home  >  Q&A  >  body text

Modal transitions in ReactJS Tabler/Bootstrap

I'm building a Tabler dashboard using some ReactJS components. At first I used normal HTML pages and Jinja2 templates, but I started implementing ReactJS for some components.

I don't want to use too many third-party tools like react-tabler or bootstrap-tabler because it creates a lot of extra packages that I probably don't really need. I've been able to create a beautiful Tabler dashboard using ReactJS components without the need for these packages.

The only problem I have right now is showing the modal...right now this works, but the CSS transitions don't. At least not at first. I made them work like this:

// handle button click
const handleEditClick = (row) => {
    setIsModalOpen(true);
    modalRef.current.style.display = "block";

    // delay to make sure block is set first
    setTimeout(() => {
        modalRef.current.classList.add("show");
    }, 100);
};

The problem is, I don't really like this. It feels a bit cliche.

The display modal works fine, just add the style="display:block attribute first and then the show class. This way I can do it without too much extra JavaScript or works without other content. But display:block must be set first, if not, they seem to be set at the same time, or maybe display:block is set later, so you don't You will see the conversion.

I tried adding the following event lister modalRef.current.addEventListener("transitionend", handleTransitionEnd);, but I guess this only works for the actual transition and not for changing the style.

Is there a cleaner way than a 100 millisecond timeout? Apparently I can't add display:block by default because then my app will be inaccessible due to the transparent mode that is on top of my app.

P粉071559609P粉071559609370 days ago513

reply all(1)I'll reply

  • P粉274161593

    P粉2741615932024-02-18 12:28:26

    This is how I fixed it now. I used useEffect twice, this is to prevent the class "show" from being added at the same time as the display:block style.

    To close the modal, I can actually use the transitionend event listener.

    const MyComponent = () => {
        const [isModalOpen, setIsModalOpen] = useState(false);
        const [isButtonClicked, setIsButtonClicked] = useState(false);
        const modalRef = useRef(null);
    
        const [isStyleApplied, setIsStyleApplied] = useState(false);
        const [isClassApplied, setIsClassApplied] = useState(false);
    
        const handleEditClick = () => {
            setIsModalOpen(true);
            setIsButtonClicked(true);
        };
    
        useEffect(() => {
            const applyStyle = () => {
                if (modalRef.current && !isStyleApplied && isButtonClicked) {
                    modalRef.current.style.display = 'block';
                    setIsStyleApplied(true);
                }
            };
    
            applyStyle();
        }, [isButtonClicked, isStyleApplied]);
    
        useEffect(() => {
            const applyClass = () => {
                if (modalRef.current && isButtonClicked && isStyleApplied && !isClassApplied) {
                    modalRef.current.classList.add('show');
                    setIsClassApplied(true);
                }
            };
    
            applyClass();
        }, [isButtonClicked, isStyleApplied, isClassApplied]);
    
    
        const handleCloseModal = () => {
            setIsModalOpen(false);
    
            modalRef.current.addEventListener("transitionend", handleTransitionEnd);
            modalRef.current.classList.remove("show");
    
            function handleTransitionEnd() {
                modalRef.current.removeEventListener("transitionend", handleTransitionEnd);
                modalRef.current.style.display = "none";
            }
            setIsButtonClicked(false);
            setIsStyleApplied(false);
            setIsClassApplied(false);
        };
    
        return (
             handleEditClick(row)} href="#">Open Modal
            
        );
    }

    reply
    0
  • Cancelreply