React-Leaflet – Visualizing GeoJSON Data

leafletreact

I'm trying to visualize a GeoJSON layer on Leaflet using React-Leaflet library.
My mental process is:

  1. Click on the button which calls a method named getHospitals()
  2. getHospitals() gets the geojson layer from the backend using axios
  3. The geojson layer is saved in a variable
  4. Then, create a reference which will passed to the geojson component in order to 'update' the component (I don't know if it's correct)
  5. Update the component state with the layer and the reference (this.setState())
  6. The component renders the new geojson

The problem is the geojson doesn't appear on the map. This is the code:

import React, { Component } from "react";
import {
  MapContainer,
  TileLayer,
  LayersControl,
  ScaleControl,
  GeoJSON,
} from "react-leaflet";
import "leaflet/dist/leaflet.css";
import axios from "axios";

import "./Mapa.css";

export class Mapa extends Component {
  state = {
    geoJSON: null,
    reference: null,
  };

  /* Definición de estilos del mapa */
  style = {
    height: 600,
    margin: 10,
  };

  getHospitals = async () => {
    let hospitals = await axios.get(
      "https://cartovis-server.herokuapp.com/hospitales"
    );

    let reference = React.createRef();

    this.setState({
      geoJSON: hospitals.data,
      reference: reference
    });
  };

  render() {
    return (
      <div id="viewer">
        <MapContainer center={[38, -1]} zoom="5" style={this.style}>
          <GeoJSON
            attribution="Capa de Hospitales de ESRI"
            data={this.state.geoJSON}
            ref={this.reference}
          />
          <ScaleControl />
          <LayersControl>
            <LayersControl.BaseLayer checked name="OpenStreetMap">
              <TileLayer
                attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
              />
            </LayersControl.BaseLayer>
          </LayersControl>
        </MapContainer>
        <div className="otherLayers">
          <h4>Hospitales</h4>
          <button className="btn btn-primary" onClick={this.getHospitals}>
            Ver
          </button>
        </div>
      </div>
    );
  }
}

export default Mapa;

Any idea?

Best Answer

GeoJSON:

data is immutable. So the layer is not re-rendered when the prop changes.

You can add the following check to see the layer on the map:

{this.state.geoJSON && (
  <GeoJSON
    attribution="Capa de Hospitales de ESRI"
    data={this.state.geoJSON}
  />
)}

That way the layer is mounted when geoJSON is not null.

Related Question