feat(map): enhance map component with ref for container and cleanup logic

This commit is contained in:
AmirReza Jamali
2026-04-28 14:01:07 +03:30
parent bcea73051b
commit 013788d566
2 changed files with 25 additions and 6 deletions
@@ -1,13 +1,23 @@
"use client"; "use client";
import jsVectorMap from "jsvectormap"; import jsVectorMap from "jsvectormap";
import { useEffect } from "react"; import { useEffect, useRef } from "react";
import "@/js/us-aea-en"; import "@/js/us-aea-en";
export default function Map() { export default function Map() {
const mapContainerRef = useRef<HTMLDivElement | null>(null);
useEffect(() => { useEffect(() => {
new jsVectorMap({ let map: InstanceType<typeof jsVectorMap> | null = null;
const container = mapContainerRef.current;
if (!container) return;
// Dev Strict Mode can run effects twice; clear old markup before re-init.
container.innerHTML = "";
map = new jsVectorMap({
selector: "#mapOne", selector: "#mapOne",
map: "us_aea_en", map: "us_aea_en",
zoomButtons: true, zoomButtons: true,
@@ -37,11 +47,20 @@ export default function Map() {
}, },
}, },
}); });
return () => {
try {
map?.destroy?.();
} catch {
// jsVectorMap can throw during React Strict Mode cleanup in dev.
}
container.innerHTML = "";
};
}, []); }, []);
return ( return (
<div className="h-[422px]"> <div className="h-[422px]">
<div id="mapOne" className="mapOne map-btn" /> <div ref={mapContainerRef} id="mapOne" className="mapOne map-btn" />
</div> </div>
); );
} }
+3 -3
View File
@@ -17,11 +17,11 @@ export async function UsedDevices({
return ( return (
<div <div
className={cn( className={cn(
"grid grid-cols-1 grid-rows-[auto_1fr] gap-9 rounded-[10px] bg-white p-7.5 shadow-1 dark:bg-gray-dark dark:shadow-card", "grid grid-cols-1 grid-rows-[auto_1fr] gap-9 rounded-[10px] bg-white shadow-1 dark:bg-gray-dark dark:shadow-card",
className, className,
)} )}
> >
<div className="flex flex-wrap items-center justify-between gap-4"> <div className="flex flex-wrap items-center justify-between gap-4 p-7.5">
<h2 className="text-body-2xlg font-bold text-dark dark:text-white"> <h2 className="text-body-2xlg font-bold text-dark dark:text-white">
Used Devices Used Devices
</h2> </h2>
@@ -29,7 +29,7 @@ export async function UsedDevices({
<PeriodPicker defaultValue={timeFrame} sectionKey="used_devices" /> <PeriodPicker defaultValue={timeFrame} sectionKey="used_devices" />
</div> </div>
<div className="grid place-items-center"> <div className="grid place-items-center pb-7.5">
<DonutChart data={data} /> <DonutChart data={data} />
</div> </div>
</div> </div>