Произвольная функция при щелчке маркера React-Leaflet

React-leaflet прекрасно предоставляет возможность помещать контент в Popup маркера.

Например, в моем примере:

            <Marker position={[item.lat, item.lng]} key={item.machineid}>
              <Popup maxWidth={720}>
                <ItemGrid machineid={item.machineid}
                          username={this.props.username}/>
              </Popup>
            </Marker>

Однако, если этот контент слишком велик, он может быть громоздким, особенно на мобильных устройствах. Я хотел бы, чтобы модальный интерфейс (начальной загрузки) активировался одним щелчком маркера. Есть ли способ сделать это в листовке React?


person notconfusing    schedule 01.12.2016    source источник


Ответы (4)


Обновление: Событие поведения №

Используйте функцию прослушивателя eventHandlers внутри компонента Marker:

<Marker
  position={[50.5, 30.5]}
  eventHandlers={{
    click: (e) => {
      console.log('marker clicked', e)
    },
  }}
/>
person Selmi Karim    schedule 24.11.2020
comment
Хотел бы я +5 к этому (и нашел его вчера, когда терял рассудок) - person lys; 02.03.2021

В соответствии с документами по реакции,

Leaflet предоставляет собственные события, отличные от React. Вы можете прослушать их с помощью React-Leaflet, добавив обратный вызов к свойству с префиксом on. Пример: <Map onMoveend={this.handleMoveend}>...</Map>.

Ознакомьтесь с документацией ???? Leaflet, чтобы узнать о событиях, связанных с каждым компонентом.

Поэтому мы можем использовать собственное событие onClick DOM Leaflet.

С react-leaflet это будет выглядеть примерно так:

import React, { Component } from "react"
import { Map as LeafletMap, TileLayer, Marker } from "react-leaflet"

class Map extends Component {
  handleClick = event => {
    const { lat, lng } = event.latlng
    console.log(`Clicked at ${lat}, ${lng}`)
  }

  render () {
    return (
      <LeafletMap center={[52.5134, 13.4225]} zoom={13}>
        <TileLayer attribution={attribution} url={url}>
          <Marker
            position={[52.5134, 13.4225]}
            onClick={this.handleClick} // <-- call handleClick()
          />
        </TileLayer>
      </LeafletMap>
    )
  }
}

export default Map
person Robin Métral    schedule 11.02.2019

Нашел своего рода хак для выполнения произвольного действия при нажатии на Маркер. (1) Сохраните всплывающее окно, но пусть его содержимое делает все, что вам нравится (например, открывает модальное окно по умолчанию) и (2) Скрывает div-контейнер всплывающего окна с помощью CSS.

В моем случае это выглядело так: Вид карты остался без изменений:

<Marker position={[item.lat, item.lng]} key={item.machineid}>
    <Popup maxWidth={720}>
      <ItemGrid machineid={item.machineid}
                         username={this.props.username}/>
    </Popup>
</Marker>

Затем ItemGrid, который ранее был в всплывающем окне, изменяется, чтобы включить модальное окно. (Здесь мы используем компоненты reactstrap и устанавливаем модальное окно true whnn, которое монтируется.):

class ItemGrid extends Component {
  constructor(props){
    super(props);
     this.state = {modal:false}
    this.toggle = this.toggle.bind(this);
  }

  toggle() {
    this.setState({
      modal: !this.state.modal
    });
  }

  componentDidMount() {
    this.setState({modal:true})
  }

  render()  {
    return (
      <div>
      <Modal isOpen={this.state.modal} toggle={this.toggle} className={this.props.className}>
        <ModalHeader toggle={this.toggle}>Modal Header</ModalHeader>
        <ModalBody>
          {ContentThatWasPreviouslyInPopup}
        </ModalBody>
      </Modal>
    </div>

И, наконец, в листовке CSS:

.leaflet-container a.leaflet-popup-close-button {
    position: absolute;
    top: 0;
    right: 0;
    padding: 8px 8px 0 0;
    text-align: center;
    width: 0px;
    height: 0px;
    font: 0px/0px Tahoma, Verdana, sans-serif; //DANGEROUS HACK
    color: #c3c3c3;
    text-decoration: none;
    font-weight: bold;
    background: transparent;
    }

.leaflet-popup-content-wrapper {
    padding: 1px;
    text-align: left;
    border-radius: 12px;
    width: 0px // DANGEROUS HACK
    }
person notconfusing    schedule 05.12.2016

Для людей, которые хотят передать аргумент, вы должны использовать:

<Marker
  position={[50.5, 30.5]}
  data="FooBar"
  eventHandlers={{
    click: (e) => {
      console.log(e.target.options.data);  // will print 'FooBar' in console
    },
  }}
/>
person 1_bug    schedule 30.06.2021