选择框值变更时如何重新渲染ReplayMap组件并清除旧数据?
解决方案
1. 用key强制组件重新渲染
在父组件渲染ReplayMap时,把选中的菜单值作为key传入。这样每次切换选项,React都会销毁旧的ReplayMap实例并创建新的,彻底清除旧数据和状态:
<ReplayMap key={selectedRoute} routeData={routeData[selectedRoute]} />
2. 监听数据变化,重置内部状态
在ReplayMap组件里,监听传入的routeData变化,主动清理旧的动画定时器和折线实例:
import { useEffect, useRef, useState } from 'react'; function ReplayMap({ routeData }) { const map = useRef(null); const polyline = useRef(null); const animationTimer = useRef(null); const [currentStep, setCurrentStep] = useState(0); const [isPlaying, setIsPlaying] = useState(false); // 数据变更时重置状态 useEffect(() => { // 清除旧定时器 if (animationTimer.current) { clearInterval(animationTimer.current); } // 移除地图上的旧折线 if (map.current && polyline.current) { map.current.removeLayer(polyline.current); map.current.removeSource(polyline.current); polyline.current = null; } // 重置动画进度到起点 setCurrentStep(0); setIsPlaying(false); }, [routeData]); // 组件卸载时清理资源 useEffect(() => { return () => { if (animationTimer.current) clearInterval(animationTimer.current); if (map.current && polyline.current) { map.current.removeLayer(polyline.current); map.current.removeSource(polyline.current); } }; }, []); // 剩余的地图初始化、动画逻辑... }
3. 优化播放逻辑,确保从头开始
修改播放/暂停函数,每次启动动画前都重置进度并清除旧定时器,保证只基于当前数据播放:
const toggleAnimation = () => { if (isPlaying) { clearInterval(animationTimer.current); setIsPlaying(false); } else { // 重置到起点 setCurrentStep(0); // 清理旧定时器 if (animationTimer.current) clearInterval(animationTimer.current); // 启动新动画 animationTimer.current = setInterval(() => { setCurrentStep(prev => { if (prev >= routeData.length - 1) { clearInterval(animationTimer.current); setIsPlaying(false); return prev; } return prev + 1; }); }, 100); setIsPlaying(true); } };
核心思路
- 用
key触发组件重建,彻底隔离新旧数据的状态 - 监听数据变化,手动清理旧的动画资源和折线实例
- 每次播放动画都从当前数据的起点开始,避免旧动画残留
内容的提问来源于stack exchange,提问作者program.exe
相关产品推荐
相关产品推荐

