React页面更新后Canvas动画持续加速问题求助
问题原因
每次页面更新或修改代码后,旧的动画循环未被终止,新的循环又会启动,多个requestAnimationFrame循环同时运行,导致动画速度叠加变快。你的useEffect既没有设置清理逻辑,也未把依赖项(比如r)加入依赖数组,组件更新时旧动画仍在后台运行。
解决步骤
- 保存
requestAnimationFrame的ID,在useEffect的清理函数中用cancelAnimationFrame终止旧循环 - 将
r改为useState变量(修改它时会触发组件更新) - 把
r加入useEffect的依赖数组,确保r变化时重新初始化动画并清理旧动画
修改后的代码
import React, { useEffect, useRef, useState } from "react"; const CanvasPage = () => { const canvasRef = useRef(null); const x = useRef(0); const [r, setR] = useState(50); // 改为响应式状态 const v = useRef(1); const animationIdRef = useRef(null); // 存储动画ID useEffect(() => { const canvas = canvasRef.current; if (!canvas) return; const context = canvas.getContext("2d"); const render = () => { // 保存当前动画ID animationIdRef.current = window.requestAnimationFrame(render); x.current = x.current + v.current; if(x.current > canvas.width){ v.current = -1; } if(x.current <= 0){ v.current = 1; } context.clearRect(0, 0, canvas.width, canvas.height); context.beginPath(); context.arc(x.current, 75, r, 0, 2 * Math.PI); context.stroke(); }; animationIdRef.current = window.requestAnimationFrame(render); // 清理函数:组件卸载或依赖变化时终止旧动画 return () => { if (animationIdRef.current) { window.cancelAnimationFrame(animationIdRef.current); } }; }, [r]); // 加入r作为依赖,r变化时重新执行effect return ( <div className="Canvas"> <h1>Canvas page</h1> {/* 测试用按钮:修改r值验证效果 */} <button onClick={() => setR(prev => prev + 10)}>增大半径</button> <button onClick={() => setR(prev => prev - 10)}>减小半径</button> <canvas id="canvas" ref={canvasRef} height="500px" width="500px" /> </div> ) } export default CanvasPage;
关键改动说明
animationIdRef:存储每次requestAnimationFrame返回的ID,确保清理时能精准终止对应的动画循环。- 清理函数:
useEffect返回的函数会在组件卸载或依赖项变化时执行,用于终止旧动画,避免多循环叠加。 r改为useState:让r成为响应式状态,修改它时触发组件重新渲染,进而触发useEffect的清理与重新初始化。- 依赖数组加入
r:确保r变化时,旧动画被清理,新动画使用最新的r值启动。
内容的提问来源于stack exchange,提问作者Enoki
相关产品推荐
相关产品推荐

