Martin
Martin

Reputation: 25

React-leaflet problem to create <Marker> <Popup> instance dynamic

I would like to create a react-leaflet object dynamically. Normal leaflet objects work, but react-leaflet do not. Code example on: https://codesandbox.io/s/show-problem-react-leaflet-marker-popup-object-hm0o8?file=/src/MapView.js

Left click shows the desired behavior with leaflet objects and right click the problem with react-leaflet.

problem code:

var lat = e.latlng.lat;
var lon = e.latlng.lng;
// create popup contents
    
// use <Marker> from react-leaflet
var newMarker = <Marker position={[lat, lon]}>
  {/* use Edit Popup */}
  <Popup editable open>   
    Your stylable content here.
  </Popup>
</Marker>;
    
// Problem addTo(map) 
newMarker.addTo(map);

Upvotes: 0

Views: 759

Answers (1)

Seth Lutske
Seth Lutske

Reputation: 10792

newMarker is a react element. You can't call the leaflet method addTo on it, because it is not a leaflet L.Marker instance.

If you want to be able to manage the markers through react, you would need to keep a state variable which is an array of coordinates. On map click, you can add the coordinate to that array, and then render a series of <Marker /> elements from that.

In your event handlers, you're simply going to capture the position of the click and pass it to a callback setMarkers:

function MyRightClickEventHandler({ setMarkers }) {
  useMapEvents({
    contextmenu: (e) => {
      setMarkers(e.latlng);
    }
  });
  return null;
}

setMarkers is a callback to setState on your primary MapView component, which adds the latlng to the state variable, which contains an array of latlngs:

// inside you'r MapContainer:
<MyRightClickEventHandler
  setMarkers={(markers) =>
    this.setState({ 
      MarkerArray: [...this.state.MarkerArray, markers] 
    })
  }
/>

Then map over the latlngs that are in that state variable, if there are any:

{this.state.MarkerArray &&
  this.state.MarkerArray.map((latlng) => (
    <Marker position={latlng}>
      <Popup editable removable>
        Thanks for using my editable popup plugin!
      </Popup>
    </Marker>
  ))}

Working codesandbox

Note that if you're going to use the editable, removable, or open props on editable popups rendered dynamically from an array, be sure to read my section on using editable popups rendered from a dynamic state array - it can get hairy if you're not careful. Feel free to ask questions in the comments if you run into problems.

Upvotes: 1

Related Questions