1

Using React Leaflet I can quite happily get a LayerControl through which I can enable/disable Leaflet Marker LayerGroups, but can't fathom how I can do do this programmatically.

Example LayerControl

The Leaflet documentation suggests something along the lines of:

var layer = L.marker(latlng).addTo(map);
layer.addTo(map);
layer.remove();

And similarly this Leaflet issue suggests keeping track of the your own layers. But how do I do this in React-Leaflet? It feels like it's abstracted too much away.

I've simplified React Leaflets's example/components/layers-control.js to isolate the issue but can't get at any of the elements:

class App extends Component {
  render() {
    return (
      <div className='map'>
        <Map className='map' center={[51,0]} zoom={10} id='map1'>
          <LayersControl position="topright" id="lc1">
              <TileLayer
              attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
              url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
              id="tl1"
              />

            <Overlay name="Layer 1" id="l1">
              <LayerGroup id="lg1">
                <Marker position={[51, 0.1]}></Marker>
              </LayerGroup>
            </Overlay>

            <Overlay name="Layer 2">
              <LayerGroup>
                <Marker position={[51, 0.2]}></Marker>
              </LayerGroup>
            </Overlay>

          </LayersControl>
        </Map>
      </div>
    );
  }
}

1 Answer 1

3

You can achieve that using refs to keep track of the map instance and the overlay instances respectively and then using some vanilla leaflet code as you would do without React:

const mapRef = useRef();
const firstOverlayRef = useRef();
const secondOverlayRef = useRef();

const addLayers = () => {
  if (mapRef.current && firstOverlayRef.current) {
      const map = mapRef.current.leafletElement;
      const firstLayer = firstOverlayRef.current.leafletElement;
      const secondLayer = secondOverlayRef.current.leafletElement;
      [firstLayer, secondLayer].forEach(layer => map.addLayer(layer));
  }
};

const removeLayers = () => {
  if (mapRef.current && firstOverlayRef.current) {
      const map = mapRef.current.leafletElement;
      const firstLayer = firstOverlayRef.current.leafletElement;
      const secondLayer = secondOverlayRef.current.leafletElement;
      [firstLayer, secondLayer].forEach(layer => map.removeLayer(layer));
  }
};

....

 <Map center={center} zoom={10} style={{ height: "90vh" }} ref={mapRef}>
        <LayersControl position="topright">
          <TileLayer
            attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
            id="tl1"
          />

          <Overlay name="Layer 1">
            <LayerGroup id="lg1" ref={firstOverlayRef}>
              <Marker position={[51, 0.1]} icon={icon} />
            </LayerGroup>
          </Overlay>

          <Overlay name="Layer 2">
            <LayerGroup ref={secondOverlayRef}>
              <Marker position={[51, 0.2]} icon={icon} />
            </LayerGroup>
          </Overlay>
        </LayersControl>
  </Map>
  <button onClick={addLayers}>Add Layers</button>
  <button onClick={removeLayers}>Remove layers</button>
  ...

Demo

Sign up to request clarification or add additional context in comments.

5 Comments

i tried the linked demo as i'm working on a similar example and there is an odd case here, when pressing add or remove buttons react gives access reference error, cannot access layer2 before initialization, but if i add a console log just after layer2 initialization it works fine?!
I cannot reproduce the case you mention in the link demo
navigating the docs at this point is really confusing as you mentioned in stackoverflow.com/questions/64934285/… , the owner changed urls and links for examples, can you reference where exactly the add/remove functionality implemented by react-leaflet?
If you mean the add/remove regarding the answer it is not documented anywhere in react-leaflet's docs. In the docs you will find info only for the wrappers (Overlay, LayerGroup etc)
I would like to know how to do this with react hooks so I can toggle the visibility from a component outside of the one that defines the layer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.