React组件onMount挂载动画优化及其他实现方案咨询
现有实现优化方案
你当前的实现核心逻辑是可行的,主要可优化点是移除硬编码的250ms延迟,避免延迟过长影响体验,或延迟过短导致DOM未完成首次渲染就触发状态更新、动画失效的问题。优化后代码如下:
const Component = () => { const [mounted, setMounted] = useState(false) useEffect(() => { // 两次requestAnimationFrame确保浏览器完成首次绘制后再更新状态 requestAnimationFrame(() => { requestAnimationFrame(() => { setMounted(true) }) }) }, []) return( <nav className={classNames( 'flex justify-between items-center transform-gpu transition-transform duration-500', mounted ? 'translate-x-0' : '-translate-x-full')}> Some nav components </nav> ) }
其他onMount动画实现方案
纯CSS/Tailwind原生动画
不需要维护任何JS状态,直接定义关键帧动画即可,适合简单固定的入场动画。你可以在Tailwind配置中扩展自定义动画:// tailwind.config.js module.exports = { theme: { extend: { animation: { 'slide-in': 'slideIn 0.5s ease forwards', }, keyframes: { slideIn: { '0%': { transform: 'translateX(-100%)' }, '100%': { transform: 'translateX(0)' }, } } } } }组件中直接使用即可:
const Component = () => { return <nav className='flex justify-between items-center animate-slide-in'> Some nav components </nav> }使用react-transition-group的CSSTransition
专门处理React组件的入场/退场动画,不需要手动维护mounted状态,还支持多元素序列动画、退场动画等复杂场景:import { CSSTransition } from 'react-transition-group' const Component = () => { return ( <CSSTransition in={true} timeout={500} classNames="slide" appear> <nav className='flex justify-between items-center'> Some nav components </nav> </CSSTransition> ) }配套CSS(或Tailwind)定义
.slide-enter、.slide-enter-active类的样式即可。使用framer-motion声明式动画
代码更简洁,无需手动维护状态或定义CSS类,直接通过属性配置动画,适合复杂交互动画场景:import { motion } from 'framer-motion' const Component = () => { return ( <motion.nav initial={{ x: '-100%' }} animate={{ x: 0 }} transition={{ duration: 0.5 }} className='flex justify-between items-center' > Some nav components </motion.nav> ) }原生Web Animations API
无需引入额外依赖或定义CSS类,可动态计算动画参数,适合需要根据运行时数据调整动画的场景:const Component = () => { const navRef = useRef(null) useEffect(() => { navRef.current.animate( [{ transform: 'translateX(-100%)' }, { transform: 'translateX(0)' }], { duration: 500, easing: 'ease', fill: 'forwards' } ) }, []) return <nav ref={navRef} className='flex justify-between items-center'> Some nav components </nav> }
内容的提问来源于stack exchange,提问作者PCPbiscuit
相关产品推荐
相关产品推荐

