组件挂载时无法触发useAnimate动画的问题求助
问题解决:Framer Motion useAnimate 挂载动画不生效
问题原因
你的代码未给组件设置初始缩放状态,animate 方法是基于元素当前样式过渡到目标样式。组件挂载时元素默认 scale 为1,此时执行 animate 到 scale:1 自然不会产生动画效果。另外,卸载回调里的样式设置无意义,因为组件即将被移除,不会触发视觉变化。
修复方案
给组件元素设置初始缩放值,再通过 useAnimate 触发从初始值到目标值的过渡动画。若后续需要退出动画,需配合 AnimatePresence 组件(先解决挂载动画问题)。
修改后的 StupidComponent.tsx:
import React, { useEffect } from 'react' import { useAnimate } from 'framer-motion' export function StupidComponent() { const [scope, animate] = useAnimate() useEffect(() => { // 从初始的scale:0.5动画到scale:1 animate( scope.current, { scale: 1 }, { duration: 0.5, ease: 'easeInOut' } ) }, [animate, scope]) return ( <div ref={scope} className="p-4 bg-orange-400 text-white" // 设置初始缩放状态 style={{ transform: 'scale(0.5)' }} > This component scales to 1 when it appears. </div> ) }
扩展:添加退出动画(可选)
若要实现卸载时的动画,不能直接用 {showStupid && <StupidComponent />},需用 AnimatePresence 包裹组件并添加唯一 key,同时在组件内处理退出逻辑:
修改 App.tsx:
import { useState } from 'react' import { AnimatePresence } from 'framer-motion' import { StupidComponent } from '@/components/StupidComponent' export const App = () => { const [showStupid, setShowStupid] = useState(false) return ( <> <button onClick={() => { setShowStupid((prev) => !prev) }} > Show stupid </button> {/* 用AnimatePresence包裹,开启退出动画支持 */} <AnimatePresence> {showStupid && ( <StupidComponent key="stupid-component" /> )} </AnimatePresence> </> ) }
修改后的 StupidComponent.tsx(支持退出动画):
import React, { useEffect, useRef } from 'react' import { useAnimate } from 'framer-motion' export function StupidComponent() { const [scope, animate] = useAnimate() const isMounted = useRef(false) useEffect(() => { isMounted.current = true // 挂载动画 animate(scope.current, { scale: 1 }, { duration: 0.5, ease: 'easeInOut' }) return () => { isMounted.current = false // 触发退出动画,等待完成后再卸载组件 const animation = animate(scope.current, { scale: 0.5 }, { duration: 0.5, ease: 'easeInOut' }) animation.finished.then(() => { if (!isMounted.current) { // 动画完成后组件已标记卸载,无需额外操作 } }) } }, [animate, scope]) return ( <div ref={scope} className="p-4 bg-orange-400 text-white" style={{ transform: 'scale(0.5)' }} > This component scales to 1 when it appears, and scales back when removed. </div> ) }
关键说明
- 必须设置初始样式,确保动画有初始值与目标值的差异
- 退出动画依赖
AnimatePresence,它会等待组件内动画完成后再执行卸载 - 用
useRef标记组件挂载状态,避免动画完成后出现内存泄漏问题
内容的提问来源于stack exchange,提问作者Bersan
相关产品推荐
相关产品推荐

