Чтобы избежать написания огромных компонентов, я хочу обернуть свой компонент Leaflet Map и внедрить дочерние элементы из различных частей кода через порталы.
Мое приложение основано на карте, поэтому в зависимости от маршрутаможет отображать тепловую карту, маркеры, фигуры и т. д.
My Map Wrapper очень прост:
<LeafletMap {...props}>
<TileLayer url={tilesSource} />
<div id={mapPortalId} />
</LeafletMap>
Мой компонент портала уже включает withLeaflet
const MapPortalRaw = ({ children, id }: IProps) => {
const containerRef = useRef<HTMLElement | null>(null);
const getContainer = () => {
if (!containerRef.current) {
containerRef.current = document.createElement('div');
containerRef.current.setAttribute(
'data-testid',
`map-portal-${id}`,
);
}
return containerRef.current;
};
const modalRoot = getPortalSource();
useEffect(() => {
if (!modalRoot) {
return;
}
modalRoot.appendChild(getContainer());
return () => {
modalRoot.removeChild(getContainer());
};
}, [modalRoot]);
return createPortal(children, getContainer());
};
export const MapPortal = compose<IProps, IProps>(withLeaflet)(MapPortalRaw);
<MapPortal id="asd">
<HeatmapLayer
points={addressPoints}
longitudeExtractor={(m: any) => m[1]}
latitudeExtractor={(m: any) => m[0]}
intensityExtractor={(m: any) => parseFloat(m[2])}
/>
</MapPortal>
К сожалению, этоне работает, так как HeatmapLayer
, кажется, не может получить доступ к контексту из карты листовки.Помещение прямо как дети работает нормально.