React Leaflet: Add markers dynamically

守給你的承諾、 提交于 2020-06-24 22:27:16

问题


How to add markers dynamically to React-Leaflet maps?

I want to add new markers when user clicks on map. And I cannot get it work.

import React, { Component } from 'react'
import { render } from 'react-dom';
import Control from 'react-leaflet-control';
import { Map, Marker, Popup, TileLayer, ZoomControl, ScaleControl } from 'react-leaflet';
import './Points.scss'

export default class PointsMap extends Component {
  state = {
    lat: 50.2, 
    lng: 30.2,
    zoom: 13,
  }

  handleClick = (e) => {
    this.addMarker();
  }

  addMarker() {

    // A) Following raises error:  
    var marker3 = L.marker([50.5, 30.5]).addTo(this.refs.map);

    // B) With following marker doesn't appear on map:
    const position2 = [50,30];      
    <Marker map={this.refs.map} position={position2} />
  }

  render () {
    const position = [this.state.lat, this.state.lng]
    return (
      <Map ref='map' center={position} zoom={this.state.zoom} onClick=    {this.handleClick} >
        <ZoomControl position="topright" />
        <ScaleControl position="bottomright" />
        <TileLayer
      attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
      url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
    />
    <Marker map={this.refs.map} position={position} >
      <Popup>
        <span>A pretty CSS3 popup. <br /> Easily customizable.</span>
      </Popup>
    </Marker>
  </Map>

    )
  }
}

In addMarker() I try to add new marker. I try to do that on 2 ways:

A)

 var marker3 = L.marker([50.5, 30.5]).addTo(this.refs.map);

It raises error:

 Uncaught TypeError: map.addLayer is not a function
     at NewClass.addTo (leaflet-src.js:3937)
     at PointsMap.addMarker (Points.js?12f5:54)

B)

const position2 = [50,30];      
    <Marker map={this.refs.map} position={position2} />

It doesn't add any new marker and it doesn't raise any error.

Do you have any idea how to add/remove markers dynamically?


回答1:


In order to get the most out of react-leaflet you should be thinking how you can design your map rendering in a way that the react lifecycle handles both the clicks and displaying of markers. React-leaflet handles almost all of the leaflet gruntwork for you.

You should be using the component's state or props to keep track of which markers the component is displaying. So, instead of manually calling L.marker, you should simply render a new <Marker> component.

Here is the react way to add a marker after clicking on the map:

class SimpleExample extends React.Component {
  constructor() {
    super();
    this.state = {
      markers: [[51.505, -0.09]]
    };
  }

  addMarker = (e) => {
    const {markers} = this.state
    markers.push(e.latlng)
    this.setState({markers})
  }

  render() {
    return (
      <Map 
        center={[51.505, -0.09]} 
        onClick={this.addMarker}
        zoom={13} 
        >
        <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
        />
        {this.state.markers.map((position, idx) => 
          <Marker key={`marker-${idx}`} position={position}>
          <Popup>
            <span>A pretty CSS3 popup. <br/> Easily customizable.</span>
          </Popup>
        </Marker>
        )}
      </Map>
    );
  }
}

And here's a jsfiddle: https://jsfiddle.net/q2v7t59h/413/




回答2:


I used the code below and it works successfully. In this code, the user can add only one marker in a position and it can change:

pay attention to import leaflet.css file

some times there are two errors about the image loading after adding the leaflet file. for resolving these errors, import marker-icon.png and marker-shadow.png in the import part and then define the L.Marker.prototype.options.icon link below.

if the map doesn't show, add the height and width(style={{width: '100%',height: '400px'}}) to Map tag as a style

import React from 'react';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';

class OSMap extends React.Component {
    constructor() {
        super();
        this.state = {
            markers: [[35.6892, 51.3890]],
        };
    }

    addMarker = (e) => {
        const { markers } = this.state;
        markers.pop();
        markers.push(e.latlng);
        this.setState({ markers });
    }

    render() {
        let DefaultIcon = L.icon({
            iconUrl: icon,
            shadowUrl: iconShadow
        });
        L.Marker.prototype.options.icon = DefaultIcon;

        return (
            <div>
                <Map
                    center={[35.6892, 51.3890]}
                    onClick={this.addMarker}
                    zoom={13}
                    maxZoom={18}
                    minZoom={5}   
                    style={{width: '100%',height: '400px'}}
                >
                    <TileLayer
                        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                        url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
                    />
                    {this.state.markers.map((position, idx) =>
                        <Marker key={`marker-${idx}`} position={position}></Marker>
                    )}
                </Map>
            </div>
        );
    }
}

export default OSMap;


来源:https://stackoverflow.com/questions/42835692/react-leaflet-add-markers-dynamically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!