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

Mr.玲玲 阅读 29

在用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配合动画?感觉官方文档的路由示例不够覆盖这种高频切换场景…

我来解答 赞 7 收藏
二维码
手机扫码查看
1 条解答
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)

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