web-dev-qa-db-ja.com

Reactリーフレット:マーカーを動的に追加

React-Leafletマップにマーカーを動的に追加する方法は?

ユーザーがマップをクリックしたときに新しいマーカーを追加したい。そして、私はそれを働かせることができません。

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>

    )
  }
}

addMarker()では、新しいマーカーを追加しようとします。私はそれを2つの方法でやろうとします:

A)

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

エラーが発生します:

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

新しいマーカーは追加されず、エラーも発生しません。

マーカーを動的に追加/削除する方法はありますか?

9
nicq

react-リーフレットを最大限に活用するためには、どのように設計できるかを考えるべきです反応のライフサイクルがマーカーのクリックと表示の両方を処理する方法でのマップレンダリング。 Reactリーフレットは、ほとんどすべてのリーフレットのうなり声を処理します。

コンポーネントが表示しているマーカーを追跡するには、コンポーネントの状態またはプロップを使用する必要があります。したがって、L.markerを手動で呼び出す代わりに、新しい<Marker>コンポーネントをレンダリングするだけです。

地図をクリックした後にマーカーを追加する方法は次のとおりです。

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

そして、これがjsfiddleです: https://jsfiddle.net/q2v7t59h/413/

23
Evan Siroky

以下のコードを使用したところ、問題なく動作しました。このコードでは、ユーザーは位置にマーカーを1つだけ追加でき、変更できます。

leaflet.cssファイルのインポートに注意してください

場合によっては、リーフレットファイルを追加した後、画像の読み込みに関して2つのエラーが発生します。これらのエラーを解決するには、インポートパーツにmarker-icon.pngとmarker-shadow.pngをインポートしてから、以下のL.Marker.prototype.options.iconリンクを定義します。

地図が表示されない場合は、高さと幅(style = {{width: '100%'、height: '400px'}})をスタイルとしてMapタグに追加します

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