Visual Studio中React Vite项目Framer Motion退出动画失效求助
1. 给路由组件配置唯一key
AnimatePresence依赖子元素的唯一key识别组件挂载/卸载状态,路由场景下必须将location.pathname作为key传入。检查你的AnimatedRoutes.jsx,确保结构如下:
import { AnimatePresence } from "framer-motion"; import { Routes, Route, useLocation } from "react-router-dom"; function AnimatedRoutes() { const location = useLocation(); return ( <AnimatePresence mode="wait"> {/* 启用wait模式,确保退出动画完成后再执行进入动画 */} <Routes location={location} key={location.pathname}> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </AnimatePresence> ); }
注意:必须把location传递给Routes组件,同时设置key={location.pathname},否则路由切换时AnimatePresence无法识别组件卸载动作。
2. 校验退出动画变体定义
打开animation.jsx,确认exit变体的动画属性正确配置,示例如下:
export const pageVariants = { initial: { opacity: 0, y: 20 }, in: { opacity: 1, y: 0 }, out: { opacity: 0, y: -20 } // 必须明确定义退出时的动画状态 }; export const pageTransition = { duration: 0.5, ease: "easeInOut" };
同时在页面组件(如About.jsx)中正确引用exit属性:
import { motion } from "framer-motion"; import { pageVariants, pageTransition } from "./animation"; function About() { return ( <motion.div initial="initial" animate="in" exit="out" // 必须指定对应退出变体 variants={pageVariants} transition={pageTransition} > {/* 页面内容 */} </motion.div> ); }
若未设置exit属性或变体定义错误,退出动画不会触发。
3. 确保AnimatePresence直接子元素为可检测组件
不要在AnimatePresence与路由组件之间添加非motion包裹组件,否则会导致AnimatePresence无法检测子组件卸载:
❌ 错误示例:
<AnimatePresence> <div className="container"> {/* 非motion包裹会阻断卸载检测 */} <Routes location={location} key={location.pathname}>...</Routes> </div> </AnimatePresence>
✅ 正确做法:将包裹容器改为motion.div,或直接把Routes作为AnimatePresence的直接子元素。
4. 检查Framer Motion版本兼容性
查看package.json中的framer-motion版本,若使用React Router v6,需确保Framer Motion版本在v4.0以上(低版本对React Router v6支持存在问题)。示例依赖配置:
{ "dependencies": { "framer-motion": "^10.0.0", "react-router-dom": "^6.8.0" } }
版本过低时,执行npm install framer-motion@latest更新至最新稳定版。
5. 排查React Strict Mode影响
在Vite的main.jsx中,若启用了<React.StrictMode>,开发环境下会触发两次组件挂载/卸载,可能中断退出动画。可暂时注释Strict Mode测试:
// 注释前 ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <App /> </React.StrictMode> ); // 注释后测试 ReactDOM.createRoot(document.getElementById('root')).render( <App /> );
若测试后退出动画正常,说明是Strict Mode的开发环境特性导致,生产环境不会出现该问题,或可保留Strict Mode并调整动画逻辑适配。
内容的提问来源于stack exchange,提问作者Joel Munoz

