如何将 onClick 事件的位置添加到钩子上?

IT技术 javascript reactjs react-leaflet
2021-05-09 09:01:19

我的代码在这里:

import { MapContainer, TileLayer } from "react-leaflet";
import React, { useState } from 'react';


    export default function App() {
      const [newLat, setNewLat] = useState(null);
      const [newLng, setNewLng] = useState(null);
    
    <MapContainer 
        center={[49.1951, 16.6068]} 
        zoom={defaultZoom} 
        scrollWheelZoom={false}
        eventHandlers={{
              click:(event)=>{
              setNewLat(event.latlng.lat());
              setNewLng(event.latlng.long());
              console.log(newLat, newLng);
              },
        }}>
    <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
      </MapContainer>

问题是当我点击地图时没有任何react,我的错误是什么?谢谢!

1个回答

react-leaflet v3至少下列选项可以考虑附加click在地图上的事件处理程序(也包括在官方文档):

选项 1:通过useMapEvents钩子

function MyMap() {
  const [loc, setLoc] = useState(null);
  const map = useMapEvents({
    click: (e) => {
      setLoc(e.latlng);
      console.log(e.latlng.lat, e.latlng.lng);
    },
 
  })
  return null
}

export default function App() {
  return (
    <MapContainer
      center={[49.1951, 16.6068]}
      zoom={defaultZoom}
      scrollWheelZoom={false}
    >
      <TileLayer
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      ></TileLayer>
      <MyMap />
    </MapContainer>
  );
}

选项 2:通过useMapEvent钩子

与选项1的区别,后者支持将单个 事件处理程序附加到地图实例

function MyMap() {
  const [loc, setLoc] = useState(null);
  const map = useMapEvent('click', (e) => {
      setLoc(e.latlng);
      console.log(e.latlng.lat, e.latlng.lng);
  })
  return null
}

export default function App() {
  return (
    <MapContainer
      center={[49.1951, 16.6068]}
      zoom={defaultZoom}
      scrollWheelZoom={false}
    >
      <TileLayer
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      ></TileLayer>
      <MyMap />
    </MapContainer>
  );
}

选项 3:通过MapConsumer组件

function Map() {
  const [loc, setLoc] = useState(null);
  return (
    <MapContainer
      center={[49.1951, 16.6068]}
      zoom={defaultZoom}
      scrollWheelZoom={false}
    >
      <TileLayer
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      ></TileLayer>
      <MapConsumer>
        {(map) => {
          map.on("click", (e) => {
            setLoc(e.latlng);
            console.log(e.latlng.lat, e.latlng.lng);
          });

          return null;
        }}
      </MapConsumer>
    </MapContainer>
  );
}

选项 4:使用useMap钩子

function MyMap() {
  const [loc, setLoc] = useState(null);
  const map = useMap();
  map.on("click", (e) => {
     setLoc(e.latlng);
     console.log(e.latlng.lat, e.latlng.lng);
  });
  return null
}

function App() {
  return (
    <MapContainer
      center={[49.1951, 16.6068]}
      zoom={defaultZoom}
      scrollWheelZoom={false}
    >
      <TileLayer
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      ></TileLayer>
      <MyMap />
    </MapContainer>
  );
}

选项 5:创建地图后,事件将附加到底层地图实例 ( whenCreated):

function Map() {
  const [loc, setLoc] = useState(null);


  function hanleMapCreated(map){
    map.on("click", (e) => {
       setLoc(e.latlng);
       console.log(e.latlng.lat, e.latlng.lng);
    });
  }

  return (
    <MapContainer
      center={[49.1951, 16.6068]}
      zoom={defaultZoom}
      scrollWheelZoom={false}
      whenCreated={hanleMapCreated}
    >
      <TileLayer
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      ></TileLayer>
    </MapContainer>
  );
}