ReactJS - Предотвратить начальную анимацию модального с реактивными крючками - PullRequest
0 голосов
/ 15 декабря 2018

Я построил простой модальный компонент, который будет скользить снизу при открытии.Анимации работают нормально, когда нажата модальная триггерная кнопка и задний фон.Но я вижу сдвигающуюся анимацию при начальном рендере страницы.Как я могу предотвратить начальную анимацию ??Я специально смотрю, как решить с реактивными крючками.

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;
}

демо (codesandbox): https://codesandbox.io/s/l7x5p4k82m

Спасибо!

1 Ответ

0 голосов
/ 15 декабря 2018

Более простой способ сделать это с classNames, поскольку прямой доступ к DOM не рекомендуется использовать с DOM.modalEl.current ref присваивается после начального рендеринга, его можно использовать как флаг, что компонент был смонтирован:

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

Применение класса hide при монтировании компонента в useEffect может привести к краткому показу модального режимаанимация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...