Framer Motion变体中Transition不生效,寻求解决方案
针对你遇到的Modal变体状态生效但transition动画不工作的问题,这里有几个实际的修复方向:
1. 给AnimatePresence内的Modal组件添加唯一Key
当前你的Modal在AnimatePresence中没有指定key,当openModal状态切换时,AnimatePresence无法正确识别组件的挂载/卸载行为,这会直接导致exit动画无法触发。修改渲染Modal的代码:
<AnimatePresence initial={false} exitBeforeEnter={true} onExitComplete={() => null} > {openModal && <Modal key="modal" openModal={openModal} handleClose={close} />} </AnimatePresence>
固定的key="modal"可以让AnimatePresence准确追踪组件的生命周期变化。
2. 调整Spring动画参数,移除冲突的duration属性
Framer Motion的spring过渡中,duration参数和物理参数(damping、stiffness)存在冲突——spring动画的时长由物理参数自动计算,手动设置duration会覆盖原本的物理行为,导致动画异常。同时给exit变体也添加过渡配置,确保退出动画生效:
const dropIn = { hidden: { y: "-100vh", opacity: 0 }, visible: { y: 0, opacity: 1, transition: { type: "spring", damping: 100, stiffness: 500, }, }, exit: { y: "100vh", opacity: 0, transition: { type: "spring", damping: 100, stiffness: 500, } }, };
3. 避免组件重渲染干扰动画状态
你的Modal组件内部使用了useFetch,当isLoading或data变化时会触发重渲染。确保motion.div的key不会变化(当前key={2}是固定值,没问题),同时可以把initial="hidden"改为initial={false},让AnimatePresence来控制初始状态,避免组件重渲染时重复触发初始动画:
<motion.div onClick={(e) => e.stopPropagation()} className="popup popup__blue" variants={dropIn} key={2} initial={false} // 由AnimatePresence控制初始状态 animate="visible" exit="exit" >
4. 检查Backdrop组件的渲染逻辑
如果Backdrop组件在Modal卸载时被直接移除(比如没有被包含在AnimatePresence的动画序列中),可能会导致motion.div的动画被中断。可以把Backdrop也改为motion组件,并和Modal内容一起放在AnimatePresence的渲染范围内,确保两者的动画同步执行。
内容的提问来源于stack exchange,提问作者Yann Ducret

