Framer Motion不透明度关键帧仅首次渲染触发动画问题
问题原因
Framer Motion 执行变体动画时,默认会对比当前元素的属性值和目标变体的属性终值,当两者完全相等时会跳过该属性的动画流程。你的两个变体conditionA和conditionB的opacity终值都是1,首次渲染动画到1之后,后续切换变体时Framer Motion判定opacity没有变更需求,因此不会触发过渡;而两个变体的高度终值不同,所以每次切换都能正常执行动画。
解决方案
最简单的处理方式是给motion.span元素绑定和切换状态关联的key属性,每次状态变更时React会销毁旧元素、渲染新的motion元素,所有动画都会从头触发,仅需对你的代码做极小改动:
import { motion } from "framer-motion"; import { useState } from "react"; export default function App({ href = "#", label, icon, notifCount }) { const [conditionIsMet, setConditionIsMet] = useState(false); const notifVariants = { conditionA: { opacity: [0, 1], height: ["40px", "90px"] }, conditionB: { opacity: [0, 1], height: ["40px", "200px"] } }; return ( <> {`Condition is ${conditionIsMet ? "A" : "B"}`} <button onClick={() => setConditionIsMet(!conditionIsMet)}>切换状态</button> <motion.span key={conditionIsMet} // 新增和状态绑定的key属性 animate={conditionIsMet ? "conditionA" : "conditionB"} variants={notifVariants} /> </> ); }
如果你不想销毁重建元素,也可以通过自定义变体传参强制重置opacity起始值,或者搭配AnimatePresence组件实现退场+入场的连贯动画,上述加key的方案改造成本最低,完全可以匹配你的需求。
内容的提问来源于stack exchange,提问作者Shahriar
相关产品推荐
相关产品推荐

