如何阻止Framer Motion动画在组件重渲染时重复执行
解决Framer Motion页面重渲染重复触发动画的问题
核心问题原因
你当前的代码里,每次组件重渲染都会重新创建MotionCard这个包装组件,Framer Motion会把它识别成全新的元素,所以每次都会重新执行初始动画。另外,动画没有绑定挂载时机,只要组件更新就会触发。
具体解决方案
把Motion包装组件移到外部
不要在组件内部定义const MotionCard = motion(Card);,把它放到组件函数外面,这样只会创建一次,不会随组件重渲染重复生成:// 移到组件外部,全局只创建一次 const MotionCard = motion(Card); const WrapperLoginFlow = () => { return ( <MotionCard initial={{ scale: 0, opacity: 0 }} animate={{ scale: 1, opacity: 1 }} transition={{ duration: 0.5 }} > <div> something </div> </MotionCard> ) };用状态+useEffect控制动画触发时机
如果组件本身有频繁的状态更新,还可以通过状态来控制动画只在首次挂载时执行:const MotionCard = motion(Card); const WrapperLoginFlow = () => { const [isFirstMount, setIsFirstMount] = useState(false); // 仅在组件首次挂载时触发状态更新 useEffect(() => { setIsFirstMount(true); }, []); return ( <MotionCard initial={{ scale: 0, opacity: 0 }} // 只有首次挂载后才执行动画 animate={isFirstMount ? { scale: 1, opacity: 1 } : {}} transition={{ duration: 0.5 }} > <div> something </div> </MotionCard> ) };固定元素的key值
如果组件存在条件渲染场景,给Motion组件设置一个固定的key,让Framer Motion识别这是同一个元素,避免重渲染时重置动画:<MotionCard key="login-flow-card" initial={{ scale: 0, opacity: 0 }} animate={{ scale: 1, opacity: 1 }} transition={{ duration: 0.5 }} > <div> something </div> </MotionCard>
内容的提问来源于stack exchange,提问作者ali safaeyan
相关产品推荐
相关产品推荐

