首页 > 解决方案 > ReactJS - 使用反应钩子防止模态的初始动画

问题描述

我构建了一个简单的 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;

模态的.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

谢谢!

标签: javascriptcssreactjscss-animationsreact-hooks

解决方案


一个更简单的方法是这样做,classNames因为不鼓励使用 DOM 直接访问 DOM。modalEl.currentref 在初始渲染后分配,它可以用作组件已安装的标志:

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

在组件安装上应用hideuseEffect可能会导致简要显示模态动画。


推荐阅读