如何使用React-Transition-Group实现模态框/对话框的显隐动画?
解决方案
核心问题原因
你之前把CSSTransition集成到组件内部不生效,最核心的原因是:如果父组件使用{show && <Confirm />}的条件渲染逻辑,会在隐藏时直接卸载整个Confirm组件,放在内部的CSSTransition根本没有触发退出动画的机会,直接被销毁了。
具体修改步骤
第一步:调整父组件调用逻辑,移除条件渲染,将显示状态作为props传入Confirm组件
父组件代码示例:const [showConfirm, setShowConfirm] = useState(false) // 直接传visible属性,不要加条件渲染 <Confirm visible={showConfirm} onClose={() => setShowConfirm(false)} />第二步:把CSSTransition集成到Confirm组件内部,控制DOM的挂载卸载和动画触发
Confirm.jsx代码示例:import { CSSTransition } from 'react-transition-group' const Confirm = ({ visible, onClose }) => { return ( <CSSTransition in={visible} timeout={300} // 数值和后续设置的动画时长保持一致 classNames="modal" unmountOnExit // 动画结束后自动卸载DOM节点 > {/* 原来的Dialog组件内容 */} <div className="fixed inset-0 z-50 flex items-center justify-center p-4"> {/* 蒙层 */} <div className="absolute inset-0 bg-black/50" onClick={onClose} /> {/* 内容区 */} <div className="relative bg-white rounded-lg p-6 w-full max-w-md"> <h3 className="text-lg font-medium mb-4">确认操作</h3> <p className="mb-6">你确定要执行该操作吗?</p> <div className="flex justify-end gap-3"> <button className="px-4 py-2 border rounded" onClick={onClose}>取消</button> <button className="px-4 py-2 bg-blue-500 text-white rounded" onClick={onClose}>确认</button> </div> </div> </div> </CSSTransition> ) } export default Confirm第三步:添加对应的动画样式,和Tailwind的动效标准对齐
全局CSS中添加以下代码:/* 蒙层淡入淡出动画 */ .modal-enter .absolute { opacity: 0; } .modal-enter-active .absolute { opacity: 1; transition: opacity 300ms ease; } .modal-exit .absolute { opacity: 1; } .modal-exit-active .absolute { opacity: 0; transition: opacity 300ms ease; } /* 内容区上浮+淡入淡出动画 */ .modal-enter .relative { opacity: 0; transform: translateY(-1rem); } .modal-enter-active .relative { opacity: 1; transform: translateY(0); transition: all 300ms ease; } .modal-exit .relative { opacity: 1; transform: translateY(0); } .modal-exit-active .relative { opacity: 0; transform: translateY(-1rem); transition: all 300ms ease; }
注意事项
- CSSTransition的
timeout属性值必须和CSS中设置的transition时长完全一致,否则会出现动画截断的问题 - 如果要实现蒙层和内容的错落动画,可以给两个元素分别设置不同的transition延迟即可
- 不要在CSSTransition外层再加条件渲染逻辑,所有的显隐控制都通过
in属性来触发
内容的提问来源于stack exchange,提问作者Reinier68
相关产品推荐
相关产品推荐

