AnimatePresence搭配clipPath inset时模态框关闭动画不生效
AnimatePresence 搭配 clipPath 实现模态框收拢退出动画不生效排查指引
以下是按出现概率从高到低排序的排查点:
- 确认被
AnimatePresence包裹的模态框根节点绑定了唯一稳定的key属性AnimatePresence依赖子元素的 key 值追踪元素生命周期,如果缺失key、key值在状态切换时异常变动,框架无法识别元素的退出状态,会直接卸载节点跳过退出动画流程。 - 核对
clipPath动画的三个状态值配置与属性写法
实现从下向上收拢效果的正确属性配置参考如下,注意clipPath必须写小驼峰格式,inset参数顺序为inset(上偏移 右偏移 下偏移 左偏移):
常见配置错误包括:属性名写成带横杠的<motion.div key="base-modal" initial={{ clipPath: "inset(100% 0 0 0)" }} animate={{ clipPath: "inset(0 0 0 0)" }} exit={{ clipPath: "inset(100% 0 0 0)" }} transition={{ duration: 0.3 }} > 模态框内容 </motion.div>clip-path、inset偏移方向写反、值缺少单位/百分比符号、exit状态和animate状态值完全一致,都会导致动画无效果。如果需要兼容旧版webkit内核浏览器,还需要同步配置WebkitClipPath属性和对应值。 - 检查模态框显隐的控制逻辑是否正确
触发关闭时必须通过状态变更让motion节点从DOM树中卸载,才能触发AnimatePresence的exit生命周期。如果是通过
display: none、visibility: hidden、透明度设为0这类纯样式方式隐藏元素,节点始终处于挂载状态,不会执行退出动画。
错误写法示例:
正确写法示例:// 错误:节点一直挂载,仅通过样式隐藏,无法触发exit <motion.div style={{ display: isOpen ? 'block' : 'none' }} exit={{ clipPath: "inset(100% 0 0 0)" }} /><AnimatePresence> {isOpen && ( <motion.div key="base-modal" initial={{ clipPath: "inset(100% 0 0 0)" }} animate={{ clipPath: "inset(0 0 0 0)" }} exit={{ clipPath: "inset(100% 0 0 0)" }} /> )} </AnimatePresence> - 排查AnimatePresence的属性配置与外层包裹冲突
检查是否给AnimatePresence设置了不匹配的mode属性(例如设置mode="wait"但未配置元素入场/出场的时序差),或者外层存在React严格模式开发环境重复渲染、路由强制切页、父组件提前卸载等逻辑打断动画流程,可以先剥离所有无关业务逻辑做最小demo测试,确认基础动画跑通后再叠加业务代码。
内容的提问来源于stack exchange,提问作者Allan
相关产品推荐
相关产品推荐

