此动画部分在slideUp上效果很好。但是slideDown动画(关闭)不会触发。模态上有一个x
将其关闭。是因为钩子吗?这是我第二次使用钩子,并且第一次创建自定义钩子,因此在它实际工作时非常激动!但是我被困在动画的结尾部分。
我尝试使用过渡动画,但是即使向上滑动也不起作用,因此决定移至关键帧。
感谢您的帮助。谢谢!
Component:
import React from 'react';
import PropTypes from 'prop-types';
import ReactModal from 'react-modal';
import classNames from 'classnames';
import styles from './styles.scss';
const Modal = ({isVisible, hide, header, children}) => {
const closeStyles = classNames('close-icon', styles.modalClose);
const headerStyles = classNames('h3', styles.header);
const slideAnimation = isVisible ? styles.slideUp : styles.slideDown;
const className = classNames(styles.commonModalStyles, slideAnimation)
return (
<ReactModal
isOpen={isVisible}
className={className}
overlayClassName={styles.overlay}
contentLabel={header}
>
<div className={styles.headerContainer}>
<h3 className={headerStyles}>{header}</h3>
<div className={closeStyles} onClick={hide}/>
</div>
<div className={styles.modal}>{children}</div>
</ReactModal>
);
};
Modal.propTypes = {
isVisible: PropTypes.bool,
hide: PropTypes.func,
header: PropsTypes.string,
children: PropTypes.node,
};
Modal.defaultProps = {
isVisible: false,
};
export default Modal;
自定义挂钩:
import { useState } from 'react';
const useToggle = () => {
const [isVisible, setIsVisible] = useState(false);
function toggle(event) {
event.preventDefault();
setIsVisible(!isVisible);
}
return {
isVisible,
toggle,
}
};
export default useToggle;
用法:
// import from file and render inside functional component.
const {isVisible, toggle} = useToggle();
<ModalV2 isVisible={isVisible} hide={toggle} header="Custom Header"> some content </Modal>
我的CSS代码:
.overlay {
overflow: auto;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.slideUp {
animation: slideup .2s ease-in-out;
}
.slideDown {
animation: slidedown .2s linear;
}
@keyframes slideup {
0% {transform: translateY(100%);}
100% {transform: translateY(0);}
}
@keyframes slidedown {
0% {transform: translateY(0);}
100% {transform: translateY(100%);}
}
.commonModalStyles {
overflow: auto;
position: fixed;
width: 100%;
height: 100%;
}
我写了一个自定义钩子来解决工作中的这个问题。
import { useState, useEffect, useRef, useLayoutEffect } from "react";
type UseTransition = (toggle: boolean) => [any, boolean];
const useTransition: UseTransition = toggle => {
const didMountRef = useRef(false);
const componentRef: any = useRef(null);
const [isAnimating, setIsAnimating] = useState(false);
useLayoutEffect(() => {
if (didMountRef.current) {
setIsAnimating(true);
} else {
didMountRef.current = true;
}
}, [toggle]);
useEffect(() => {
componentRef.current.addEventListener("transitionend", () => {
setIsAnimating(false);
});
}, [componentRef, setIsAnimating]);
return [componentRef, isAnimating];
};
export default useTransition;
在此处查看实际操作: