热力图数据更新后为什么不重新渲染?
我在用 React + 高德地图 SDK 做一个热力图功能,初始加载时能正常显示,但当我通过接口获取新数据并 setState 后,热力图却没更新。我确认数据格式是对的,也调用了 setHeatmapData 方法,但地图上还是旧的热力图。
是不是我漏掉了什么刷新机制?或者高德的 Heatmap 实例需要手动 destroy 再重建?试过 forceUpdate 也没用……
useEffect(() => {
if (map && heatmapData.length > 0) {
const heatmap = new AMap.Heatmap(map, {
radius: 20,
opacity: [0.6, 0.9],
});
heatmap.setDataSet({
data: heatmapData,
max: 100,
});
}
}, [map, heatmapData]);
问题的根本原因是这样的:第一次渲染时创建了 heatmap 实例并绑定了数据,之后数据变化触发 useEffect 重新执行,你又创建了一个新的实例,但这个新实例并没有替换掉地图上原来的那个,地图上显示的还是第一个实例的数据。
来解决这个问题:
第一步,用 useRef 保存 heatmap 实例的引用,这样我们才能在后续更新时访问到它。
第二步,在创建新实例前先判断是否已存在,如果存在就先调用 destroy 方法销毁,然后再创建新的。
第三步,把 heatmap 实例也放入 useEffect 的依赖数组里,确保每次数据更新都能正确处理。
完整代码如下:
这里有个关键点我解释一下:其实更新热力图数据不需要每次都销毁重建,高德的 Heatmap 提供了 setDataSet 方法,直接调用这个方法传入新数据就能更新。你只需要在第一次时创建实例,之后数据变化只用 setDataSet 更新数据就行,这样性能也会更好。
如果你确实需要完全重建(比如配置项也需要变),那就在创建新实例前调用 destroy 方法:
还有一个可能的坑:AMap.Heatmap 可能需要你手动引入插件。在创建 Heatmap 实例前,确保已经加载了 Heatmap 插件:
你可以检查一下是否有加载这个插件,如果没加载,热力图也不会显示。
总结一下:核心问题就是没有保存实例引用,导致每次数据更新都创建新实例但没有正确替换。解决方案就是用 ref 保存实例,然后判断是首次创建还是更新数据。