MapReady entregaba el mapa en el useEffect de montaje, cuando el contenedor
puede no tener tamano todavia. En FiresMap eso hacia que getBounds() lanzara;
el catch solo avisaba ("Failed to set map bounds and scale") y mapSize nunca
se seteaba, con lo que la suscripcion de fuegos por viewport NI SE CREABA:
loading eterno y tile-pane vacio (0 capas) pese a haber 7470 fuegos.
Evidencia: en Meteor.connection._subscriptions solo aparecian activefirestotal,
activefiresuniontotal, settings y userData — ninguna por localizacion.
Ahora se entrega via map.whenReady() + invalidateSize(), solo cuando getSize()
no es 0, con reintento en el evento resize y entrega unica (flag delivered).
Toca el componente compartido por todos los mapas: al desplegar hay que
re-verificar /fires, /zones, /subscriptions, home y detalle de fuego.
SIN DESPLEGAR todavia (la imagen viva es la de 01:33, sin este cambio).
42 lines
1.6 KiB
JavaScript
42 lines
1.6 KiB
JavaScript
import { useEffect } from 'react';
|
|
import { useMap, useMapEvents } from 'react-leaflet';
|
|
|
|
// v4 replaces the v1 `ref`/`.leafletElement` + handleLeafletLoad pattern: this
|
|
// child runs inside <MapContainer> 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 <Map>).
|
|
export const MapEvents = ({ handlers }) => {
|
|
useMapEvents(handlers || {});
|
|
return null;
|
|
};
|