import { useEffect } from 'react'; import { useMap, useMapEvents } from 'react-leaflet'; // v4 replaces the v1 `ref`/`.leafletElement` + handleLeafletLoad pattern: this // child runs inside and hands the ready Leaflet map to a class // parent once, so the parent can drive it imperatively (setView, fitBounds, // graphicScale, subsUnion, …). export const MapReady = ({ onReady }) => { const map = useMap(); useEffect(() => { if (!onReady) return undefined; let cancelled = false; let delivered = false; // El efecto de montaje puede correr antes de que el contenedor tenga tamaño. // Si entregamos el mapa entonces, un `getBounds()` del padre lanza y se queda // sin bounds: en /fires eso dejaba la suscripcion por viewport sin crear y el // mapa vacio (0 capas) pese a haber 7470 fuegos. Esperamos a que el mapa este // listo Y tenga tamaño real; entregamos una sola vez. const deliver = () => { if (cancelled || delivered) return; map.invalidateSize(); const size = map.getSize(); if (!size || size.x === 0 || size.y === 0) return; delivered = true; onReady(map); }; map.whenReady(deliver); map.on('resize', deliver); return () => { cancelled = true; map.off('resize', deliver); }; }, [map]); // eslint-disable-line react-hooks/exhaustive-deps return null; }; // Bridges Leaflet map events to callbacks (replaces the v1 onMoveend / // onViewportChanged / onZoomend props on ). export const MapEvents = ({ handlers }) => { useMapEvents(handlers || {}); return null; };