You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 05:45:07