Framer Motion组件卸载时动画突然中断怎么办?

Mr.玲玲 阅读 55

在用Framer Motion做页面切换动画时遇到个怪问题,当快速切换路由导致组件被卸载时,退出动画会突然中断,直接消失而不是完成整个过渡效果…

已经试过用exitBeforeEntercustom属性控制,也尝试在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配合动画?感觉官方文档的路由示例不够覆盖这种高频切换场景…

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
Mr.星星
Mr.星星 Lv1
我一般直接在动画组件外面包一层 AnimatePresence,然后给每个运动元素加上独一无二的 key 属性。记得把 exitBeforeEnter 改成 onExitComplete 回调来清理状态。

import { motion, AnimatePresence } from "framer-motion";

export const PageTransition = ({ children, location }) => (
<AnimatePresence onExitComplete={() => console.log('done')}>
<motion.div
key={location.pathname}
exit={{ opacity: 0 }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
>
{children}
</motion.div>
</AnimatePresence>
);


这样能确保即使快速切换路由,动画也能正常完成过渡。其实官方文档里是有这个用法的,只是藏得比较深...
点赞
2026-03-26 10:05
W″春萍
你这个情况我之前踩过坑,根本问题不在防抖或者 layoutGroup,而是 motion.div.extend 已经是旧写法了,现在官方早就废弃了 extend 这种方式,直接用 styled(motion.div) 或者更简单的——别封装错地方。

你的组件一卸载,动画实例就没了,自然中断。关键是得让退出动画完成后再卸载组件,靠纯 CSS 或内联配置搞不定这种异步流程。

可以优化成用 AnimatePresence 来控制整个页面容器的挂载和卸载,确保退出动画跑完才移除 DOM:

import { motion, AnimatePresence } from "framer-motion";
import { useState, useEffect } from "react";

const PageTransition = ({ children, isVisible }) => (

{isVisible && (
key="page"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
{children}

)}

);


然后在路由切换时,不要立刻改变页面状态。比如配合 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)

这样高频切换也不会断档,退出动画能播完。
点赞 13
2026-02-09 10:37