如何将原生JS实现的波浪线动画转换为React版本?
问题解答
是的,你确实需要用useState和useEffect完成改造,核心原因是React遵循状态驱动UI的理念,要避免直接操作原生DOM,同时要处理组件生命周期里的动画启停逻辑。
改造要点说明
- 固定不变的横坐标数组
xs可以直接提为组件外的常量,避免每次渲染重复生成 - 每帧都变化的
t和动画帧ID用useRef存储,不需要触发组件重渲染,性能远好于放在useState里 useState用来存储动态生成的路径d属性,驱动SVG自动更新,不需要手动操作DOM修改属性useEffect用来处理组件挂载时启动动画、卸载时清除动画的逻辑,避免内存泄漏
完整实现代码
import React, { useState, useEffect, useRef } from 'react' // 固定横坐标,不需要重复生成 const xs = Array.from({ length: 300 }, (_, i) => i) const WaveAnimation = () => { // 存储SVG路径的d属性,驱动UI更新 const [pathD, setPathD] = useState('') // 用useRef存储不需要触发重渲染的可变值 const tRef = useRef(0) const animationIdRef = useRef(null) useEffect(() => { const animate = () => { const points = xs.map(x => { const y = 200 + 8 * Math.sin((x + tRef.current) / 5) return [x, y] }) const newPath = "M" + points.map(p => `${p[0]},${p[1]}`).join(" L") setPathD(newPath) tRef.current += 0.5 animationIdRef.current = requestAnimationFrame(animate) } // 启动动画 animate() // 组件卸载时清除动画,避免内存泄漏 return () => { cancelAnimationFrame(animationIdRef.current) } }, []) return ( <div className="Startpage"> {/* 给svg设置合适的宽高,避免波浪显示不全,可按需调整样式 */} <svg width="300" height="400" viewBox="0 0 300 400"> <path d={pathD} fill="none" stroke="black" strokeWidth="2"/> </svg> </div> ) } export default WaveAnimation
内容的提问来源于stack exchange,提问作者Mieown
相关产品推荐
相关产品推荐

