Framer Motion组件卸载时动画突然中断怎么办?
在用Framer Motion做页面切换动画时遇到个怪问题,当快速切换路由导致组件被卸载时,退出动画会突然中断,直接消失而不是完成整个过渡效果…
已经试过用exitBeforeEnter和custom属性控制,也尝试在useEffect里用动画钩子手动触发,但只要切换速度超过半秒就会报错:"Attempted to clean up unmounted component"…
这是我的动画组件写法:
import { motion } from "framer-motion";
export const PageTransition = motion.div.extend({
exit: { opacity: 0, transition: { duration: 0.5 } },
initial: { opacity: 0 },
animate: { opacity: 1 },
});
难道要给动画加防抖?或者必须用layoutGroup配合动画?感觉官方文档的路由示例不够覆盖这种高频切换场景…
motion.div.extend已经是旧写法了,现在官方早就废弃了 extend 这种方式,直接用styled(motion.div)或者更简单的——别封装错地方。你的组件一卸载,动画实例就没了,自然中断。关键是得让退出动画完成后再卸载组件,靠纯 CSS 或内联配置搞不定这种异步流程。
可以优化成用
AnimatePresence来控制整个页面容器的挂载和卸载,确保退出动画跑完才移除 DOM:然后在路由切换时,不要立刻改变页面状态。比如配合 react-router,你可以用 location.key 当作 key,让 AnimatePresence 检测到变化并触发 exit 动画。
重点是:必须用
AnimatePresence包裹动态内容,否则 exit 根本不会执行。你现在写的那个 extend 只是加了个默认配置,但没解决生命周期同步问题。还有,别在组件里用
useEffect手动清理动画,Framer Motion 自己会管。那个报错“Attempted to clean up unmounted component”通常是因为你在卸载后还试图操作动画引用,一般是 ref 或 callback 没清掉。简单说就是三点:
1. 换掉 extend 写法,直接用 motion 组件传 props
2. 外层包上 AnimatePresence 控制条件渲染
3. 确保每次页面切换都能被 React 正确识别为不同实例(靠 key)
这样高频切换也不会断档,退出动画能播完。