ReactJS - Prevent initial animation of modal with react hooks

笑着哭i 提交于 2019-12-13 19:24:41

问题


I built simple Modal component which will slide from bottom when opened. Animations are working fine when Modal trigger button clicked and backdrop clicked. But i am seeing slide-down animation at initial render of page. How can i prevent initial animation ?? I am specifically looking how to solve with react hooks.

Modal.js

import React, { useRef, useEffect } from 'react';
import { createPortal } from 'react-dom';

import './Modal.css';

const Modal = ({ isOpen, onClose, children }) => {
  const modalEl = useRef(null);
  const handleCoverClick = (e) => {
    if (e.target.hasAttribute('modal')) {
      onClose();
    }
  }

  useEffect(() => {
    const handleAnimationEnd = (event) => {
      if (!isOpen) {
        event.target.classList.remove('show');
        event.target.classList.add('hide');

      } else {
        event.target.classList.remove('hide');
        event.target.classList.add('show');
      }
    };
    modalEl.current.addEventListener('animationend', handleAnimationEnd);

    return () => modalEl.current.removeEventListener('animationend', handleAnimationEnd);
  }, [isOpen]);

  return createPortal(
    <>
      <div className={`ModalCover ${isOpen ? 'show' : 'hide'}`} onClick={handleCoverClick} modal="true"></div>
      <div className={`ModalContainer ${isOpen ? 'slide-up' : 'slide-down'}`} ref={modalEl}>
        {children}
      </div>
    </>,
  document.body);
};

export default Modal;

Modal.css

.show {
    display: block;
}

.hide {
    display: none;
}

.slide-up {
    transform: translateY(0%);
    animation: slide-up 0.5s forwards;
}

.slide-down {
    transform: translateY(100%);
    animation: slide-down 0.5s forwards;
}

@keyframes slide-up {
    0% { transform: translateY(100%); }
    100% { transform: translateY(0%); }
}

@keyframes slide-down {
    0% { transform: translateY(0%); }
    100% { transform: translateY(100%); }
}

.ModalCover {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 10;
  background-color: rgba(0, 0, 0, 0.15);
}

.ModalContainer {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 400px;
  margin-top: calc(100vh - 400px);
  z-index: 20;
}

demo (codesandbox) : https://codesandbox.io/s/l7x5p4k82m

Thanks!


回答1:


A simpler way is to do this with classNames since direct DOM access is discouraged with DOM. modalEl.current ref is assigned after initial render, it can be used as a flag that a component was mounted:

<div className={`
  ModalContainer
  ${isOpen ? 'slide-up' : 'slide-down'}
  ${!modalEl.current && 'hide'}
`} ref={modalEl}>

Applying hide class on component mount in useEffect may result in briefly shown modal animation.



来源:https://stackoverflow.com/questions/53790963/reactjs-prevent-initial-animation-of-modal-with-react-hooks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!