Добавить onClick на MapContainer в компонент в 3.x

#javascript #reactjs #leaflet #react-leaflet

#javascript #reactjs #брошюра #реагировать-листовка

Вопрос:

Я использую следующие версии:

 "leaflet": "^1.7.1",
"react-leaflet": "^3.0.2",
 

Я хочу выполнить некоторые действия при щелчке по карте, например, добавить маркер.

Я попробовал подход к компонентам без состояния, который, похоже, работает, но мне это не очень нравится по нескольким причинам.

Я попытался использовать eventHandlers атрибут:

   render() {
    return <div>
          <MapContainer center={[ 48, 11 ]} zoom={10} scrollWheelZoom={true} eventHandlers={{
            click: () => {
              console.log('map clicked')
            },
          }}>
            <TileLayer .../>
          </MapContainer>
        </div>
  }
 

но он никогда не срабатывает.

Я также читал о MapConsumer, но не могу найти хороших примеров.

Приветствуются любые подсказки по созданию обработчика событий onClick.

TIA

Ответ №1:

Похоже, что eventHandlers , хотя он доступен в качестве поддержки MapContainer (если вы нажмете ctlr пробел в vscode f.i, он появится), он недоступен в официальном API и предназначен только для дочерних компонентов MapContainer , см. Здесь и здесь для Marker .

то, чего вы хотите достичь, может быть реализовано с помощью useMapEvents отдельного компонента, а затем включено в качестве дочернего элемента в MapContainer :

 function App() {
  function MyComponent() {
    const map = useMapEvents({
      click: (e) => {
        const { lat, lng } = e.latlng;
        L.marker([lat, lng], { icon }).addTo(map);
      }
    });
    return null;
  }

  return (
    <MapContainer center={[50.5, 30.5]} zoom={13} style={{ height: "100vh" }}>
      <TileLayer
        attribution='amp;copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      <MyComponent />
    </MapContainer>
  );
}
 

ДЕМОНСТРАЦИЯ

Другой подход — прослушивание whenReady prop (официально не документировано, но, похоже, работает аналогично whenCreated prop, но экземпляр map доступен через object.target ) на MapContainer :

 <MapContainer
      center={[50.5, 30.5]}
      zoom={13}
      style={{ height: "100vh" }}
      whenReady={(map) => {
        console.log(map);
        map.target.on("click", function (e) {
          const { lat, lng } = e.latlng;
          L.marker([lat, lng], { icon }).addTo(map.target);
        });
      }}
    >
    ...
</MapContainer>
 

3-й подход заключается в использовании MapConsumer в качестве дочернего элемента MapContainer (docs):

 <MapContainer center={[50.5, 30.5]} zoom={13}>
     <MapConsumer>
            {(map) => {
              console.log("map center:", map.getCenter());
              map.on("click", function (e) {
                const { lat, lng } = e.latlng;
                L.marker([lat, lng], { icon }).addTo(map);
              });
              return null;
            }}
     </MapConsumer>
</MapContainer>
 

4-й подход заключается в использовании whenCreated prop (официально документированный) на MapContainer :

 <MapContainer
      center={[50.5, 30.5]}
      zoom={13}
      style={{ height: "100vh" }}
      whenCreated={(map) => {
        map.on("click", function (e) {
          const { lat, lng } = e.latlng;
          L.marker([lat, lng], { icon }).addTo(map.target);
        });
      }}
    >
...
 

Комментарии:

1. это то, что у меня есть в atm

2. Я добавил еще два способа. Посмотрите

3. Подход с whenReady , по-видимому, удален в 3.0.2. Кроме того, документация перенаправляет результат поиска на 404…

4. whenReady есть ли, вы можете найти документ, описанный здесь.

5. Вы правы, это не задокументировано в документах, однако оно существует, попробуйте использовать его в приведенной выше демонстрации. Существует объект: { target } there available, который является экземпляром карты.