web-dev-qa-db-fra.com

React Leaflet: Ajouter dynamiquement des marqueurs

Comment ajouter dynamiquement des marqueurs aux cartes React-Leaflet?

Je veux ajouter de nouveaux marqueurs lorsque l'utilisateur clique sur la carte. Et je ne peux pas le faire fonctionner.

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>

    )
  }
}

Dans addMarker () j'essaie d'ajouter un nouveau marqueur. J'essaie de le faire de 2 façons:

UNE)

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

Cela soulève une erreur:

 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} />

Il n'ajoute aucun nouveau marqueur et ne génère aucune erreur.

Avez-vous une idée de comment ajouter/supprimer des marqueurs dynamiquement?

9
nicq

Afin de tirer le meilleur parti de réagissez - dépliant, vous devez réfléchir à la manière dont vous pouvez concevoir le rendu de votre carte dans une manière que le cycle de vie de react gère à la fois les clics et l'affichage des marqueurs. React-leaflet gère la quasi-totalité du grognement des dépliants pour vous.

Vous devez utiliser l'état ou les accessoires du composant pour garder une trace des marqueurs affichés par le composant. Ainsi, au lieu d'appeler manuellement L.marker, vous devez simplement rendre un nouveau <Marker> composant.

Voici la façon de réagir pour ajouter un marqueur après avoir cliqué sur la carte:

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>
    );
  }
}

Et voici un jsfiddle: https://jsfiddle.net/q2v7t59h/413/

23
Evan Siroky

J'ai utilisé le code ci-dessous et cela fonctionne avec succès. Dans ce code, l'utilisateur ne peut ajouter qu'un seul marqueur dans une position et il peut changer:

faites attention à l'importation du fichier leaflet.css

parfois, il y a deux erreurs concernant le chargement de l'image après l'ajout du fichier de dépliant. pour résoudre ces erreurs, importez marker-icon.png et marker-shadow.png dans la partie d'importation, puis définissez le lien L.Marker.prototype.options.icon ci-dessous.

si la carte ne s'affiche pas, ajoutez la hauteur et la largeur (style = {{width: '100%', height: '400px'}}) à la balise Map en tant que 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;
1
mohammad