Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

382
Vistas
Trying to apply zoom on click with react-leaflet

I'm trying to replicate some functions of the leaflet map https://leafletjs.com/examples/choropleth/ to react/typeScript but I'm getting an error when I try to add the function to zoom on a Feature it breaks, this is the code I'm working on

import Leaflet from 'leaflet';
import React, {
  useRef, RefObject,
} from 'react';
import {
  MapContainer, TileLayer, GeoJSON, useMap,
} from 'react-leaflet';
import styled from 'styled-components';

import { statesData } from './statesData';
import './style.css';

const EmployerLocationMap = () => {
  const geoJson: RefObject<Leaflet.GeoJSON> = useRef(null);
  const map = useMap();

  const highlightFeature = (e: Leaflet.LeafletMouseEvent) => {
    const layer = e.target;

    layer.setStyle({
      color: '#666',
      dashArray: '',
      fillOpacity: 0.7,
      weight: 5,
    });
  };

  const resetHighlight = (e: Leaflet.LeafletMouseEvent) => {
    geoJson.current?.resetStyle(e.target);
  };

  const zoomToFeature = (e: Leaflet.LeafletMouseEvent) => {
    map.fitBounds(e.target.getBounds());
  };

  return (
    <CardContainer>
      <Row>
        <Col width='60%'>
          <MapContainer
            center={[37.8, -96]}
            zoom={3}
          >
            <TileLayer
              attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
              url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
            />
            <GeoJSON
              data={statesData}
              key='usa-states'
              ref={geoJson}
              style={() => {
                return {
                  color: 'white',
                  dashArray: '3',
                  fillColor: '#f0f0f0',
                  fillOpacity: 0.7,
                  opacity: 1,
                  weight: 2,
                };
              }}
              onEachFeature={(__, layer) => {
                layer.on({
                  click: (e) => {
                    zoomToFeature(e);
                  },
                  mouseout: (e) => {
                    resetHighlight(e);
                  },
                  mouseover: (e) => {
                    highlightFeature(e);
                  },
                });
              }}
            />
          </MapContainer>
        </Col>
      </Row>

    </CardContainer>
  );
};

export default EmployerLocationMap;

and when I start the frontend i get this error on the console:

Uncaught Error: No context provided: useLeafletContext() can only be used in a descendant of <MapContainer>

at useLeafletContext

I don't get what could be wrong, I've seen several implementations on this and it looks the same.

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

useMap can only be used within a component that is itself a child/descendant of <MapContainer>. https://react-leaflet.js.org/docs/api-map/#usemap

Hook providing the Leaflet Map instance in any descendant of a MapContainer.

Here you try calling useMap in your EmployerLocationMap component, which contains a <MapContainer>, but which is obviously not a descendant of one.

A solution for your case could be to separate the map logic in another component that you can place inside the <MapContainer>:

const EmployerLocationMap = () => {
  return (
    <CardContainer>
      <Row>
        <Col width='60%'>
          <MapContainer
            center={[37.8, -96]}
            zoom={3}
          >
            <TileLayer
              attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
              url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
            />
            <MapContent />
          </MapContainer>
        </Col>
      </Row>

    </CardContainer>
  );
};

const MapContent = () => {
  const geoJson: RefObject<Leaflet.GeoJSON> = useRef(null);
  const map = useMap();

  const highlightFeature = (e: Leaflet.LeafletMouseEvent) => {
    const layer = e.target;

    layer.setStyle({
      color: '#666',
      dashArray: '',
      fillOpacity: 0.7,
      weight: 5,
    });
  };

  const resetHighlight = (e: Leaflet.LeafletMouseEvent) => {
    geoJson.current?.resetStyle(e.target);
  };

  const zoomToFeature = (e: Leaflet.LeafletMouseEvent) => {
    map.fitBounds(e.target.getBounds());
  };

  return (
            <GeoJSON
              data={statesData}
              key='usa-states'
              ref={geoJson}
              style={() => {
                return {
                  color: 'white',
                  dashArray: '3',
                  fillColor: '#f0f0f0',
                  fillOpacity: 0.7,
                  opacity: 1,
                  weight: 2,
                };
              }}
              onEachFeature={(__, layer) => {
                layer.on({
                  click: (e) => {
                    zoomToFeature(e);
                  },
                  mouseout: (e) => {
                    resetHighlight(e);
                  },
                  mouseover: (e) => {
                    highlightFeature(e);
                  },
                });
              }}
            />
  );
};
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda