How to pass and get additional data/values from react-leaflet Marker?

青春壹個敷衍的年華 提交于 2021-02-20 04:19:26

问题


I am adding a group of markers to a map using react-leaflet. At present I can display the markers on the map with a custom icon. How do add a record of data to each marker. I assume I have to somehow create a custom marker class? Does anyone now how I could add a data record to each marker or at least an index.

This is the code so far:

import React, { Component } from 'react';
import { Map, TileLayer, Marker }  from 'react-leaflet';
import {Navbar, Nav, NavDropdown}  from 'react-bootstrap';
import L from 'leaflet';
import './App.css';

class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      location: {
        lat: -41.2728,
        lng: 173.2995,
      },
      zoom: 8,
      markersData: [],
      fault: {},
      layers: [],
      bounds: {},
      icon: null
    }
  }

  componentDidMount() {
    // Call our fetch function below once the component mounts
    this.callBackendAPI()
    .catch(err => console.log(err));
  }

  componentDidUpdate() {   
    //let marker = CustomMarker();
  }

  callBackendAPI = async () => {
    const response = await fetch('http://localhost:5000/api') 
    const body = await response.json();
    console.log(body.express)
    if (response.status !== 200) {
      throw Error(body.message) 
    }
    return body;
  };

  addMarkers(data) {
    let markersData = [];
    let table = [];
    for (var i = 0; i < data.length; i++) {
      const id = data[i].gid
      const fault = data[i].fault
      let record = {id: id, fault: fault};
      table.push(record);
      const position = JSON.parse(data[i].st_asgeojson);
      const lng = position.coordinates[0];
      const lat = position.coordinates[1];
      let latlng = L.latLng(lat, lng);
      markersData.push(latlng);     
    }
    this.setState({markersData: markersData});
    this.setState({fault: table});
    console.log(this.state.markersData[0])
    console.log(this.state.fault)
  }

  /**
   * fires when user scrolls mousewheel
   * param - e the mouse event
   **/
  onZoom(e) {
    this.setState({zoom: e.target.getZoom()});
    this.setState({bounds: e.target.getBounds()});    
  }

  clickMarker(e) {
    var marker = e.target;
    console.log(marker.getLatLng());
  }

  getIcon(zoom) {
    let icon = null;
    if (zoom <= 10) {
      icon = L.icon({
      iconUrl: 'CameraRed_4px.png',
      iconSize: [4, 4],
      iconAnchor: [2, 2],
      });
    } else {
      icon = L.icon({
        iconUrl: 'CameraRed_8px.png',
        iconSize: [8, 8],
        iconAnchor: [4, 4],
        });
    }
    return icon
  }

  async loadLayer(e) {
    const response = await fetch('http://localhost:5000/layer', {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        latitude: this.state.location.lat,
        longitude: this.state.location.lng,
        menu: e.target.id
      })
    })
    if (response.status !== 200) {
      throw Error(body.message) 
    } 
    const body = await response.json();
    await this.addMarkers(body);

  };

  customMarker = L.Marker.extend({
    options: {
    id: null,
    type: ''
    }
    });

  render() {
    //console.log("render");
    const position = [this.state.location.lat, this.state.location.lng];
    const { markersData } = this.state.markersData;
    console.log(this.state.zoom);
    let icon = this.getIcon(this.state.zoom);
    this.state.icon = icon;
    return (
      <>
        <div>
          <Navbar bg="light" expand="lg"> 
          <Navbar.Brand href="#home">
            </Navbar.Brand>
          <Nav>
            <NavDropdown title="Layers" id="basic-nav-dropdown">
              <NavDropdown.Item id="AddLayer" href="#addlayer" onClick={(e) => this.loadLayer(e)}
              >Add Layer

              </NavDropdown.Item>
              <NavDropdown.Divider />
              <NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
            </NavDropdown>         
          </Nav>
          <Nav className="ml-auto">
            <Nav.Link href="#login">Login</Nav.Link>
          </Nav>
          </Navbar>
        </div>
        <div className="map">
        <Map
          ref={(ref) => { this.map = ref; }}
          className="map"
          markersData={markersData}
          worldCopyJump={true}
          center={position}
          zoom={this.state.zoom}
          onZoom={(e) => this.onZoom(e)}>
          <TileLayer
            attribution="&amp;copy <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors and Chat location by Iconika from the Noun Project"
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
          {this.state.markersData.map((position, index) => 

          <Marker key={index} position={position} icon={this.state.icon} draggable={false} onClick={(e) => this.clickMarker(e)}>
        </Marker>
        )}
        </Map> 
      </>
    );
  }
}
export default App;  

Edit:
Original question title: Extending react-leaflet marker to create custom marker.


回答1:


All of the props passed to Marker will be available in e.target.options when clicked.

{this.state.markersData.map((position, index) => (
  <Marker
    key={index}
    data={position} // <-- get this value in onClick handler
    position={position}
    icon={this.state.icon}
    draggable={false}
    onClick={e => this.clickMarker(e)}
  ></Marker>
))} 



  clickMarker(e) {
    var marker = e.target;
    console.log(marker.options.data); // logs position.
  }


来源:https://stackoverflow.com/questions/59149848/how-to-pass-and-get-additional-data-values-from-react-leaflet-marker

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